Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      5  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     23  * OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 
     27 /**
     28  * \file bufferobj.c
     29  * \brief Functions for the GL_ARB_vertex/pixel_buffer_object extensions.
     30  * \author Brian Paul, Ian Romanick
     31  */
     32 
     33 #include <stdbool.h>
     34 #include <inttypes.h>  /* for PRId64 macro */
     35 #include "util/debug.h"
     36 #include "glheader.h"
     37 #include "enums.h"
     38 #include "hash.h"
     39 #include "imports.h"
     40 #include "context.h"
     41 #include "bufferobj.h"
     42 #include "externalobjects.h"
     43 #include "mtypes.h"
     44 #include "teximage.h"
     45 #include "glformats.h"
     46 #include "texstore.h"
     47 #include "transformfeedback.h"
     48 #include "varray.h"
     49 
     50 
     51 /* Debug flags */
     52 /*#define VBO_DEBUG*/
     53 /*#define BOUNDS_CHECK*/
     54 
     55 
     56 /**
     57  * We count the number of buffer modification calls to check for
     58  * inefficient buffer use.  This is the number of such calls before we
     59  * issue a warning.
     60  */
     61 #define BUFFER_WARNING_CALL_COUNT 4
     62 
     63 
     64 /**
     65  * Helper to warn of possible performance issues, such as frequently
     66  * updating a buffer created with GL_STATIC_DRAW.  Called via the macro
     67  * below.
     68  */
     69 static void
     70 buffer_usage_warning(struct gl_context *ctx, GLuint *id, const char *fmt, ...)
     71 {
     72    va_list args;
     73 
     74    va_start(args, fmt);
     75    _mesa_gl_vdebug(ctx, id,
     76                    MESA_DEBUG_SOURCE_API,
     77                    MESA_DEBUG_TYPE_PERFORMANCE,
     78                    MESA_DEBUG_SEVERITY_MEDIUM,
     79                    fmt, args);
     80    va_end(args);
     81 }
     82 
     83 #define BUFFER_USAGE_WARNING(CTX, FMT, ...) \
     84    do { \
     85       static GLuint id = 0; \
     86       buffer_usage_warning(CTX, &id, FMT, ##__VA_ARGS__); \
     87    } while (0)
     88 
     89 
     90 /**
     91  * Used as a placeholder for buffer objects between glGenBuffers() and
     92  * glBindBuffer() so that glIsBuffer() can work correctly.
     93  */
     94 static struct gl_buffer_object DummyBufferObject;
     95 
     96 
     97 /**
     98  * Return pointer to address of a buffer object target.
     99  * \param ctx  the GL context
    100  * \param target  the buffer object target to be retrieved.
    101  * \return   pointer to pointer to the buffer object bound to \c target in the
    102  *           specified context or \c NULL if \c target is invalid.
    103  */
    104 static inline struct gl_buffer_object **
    105 get_buffer_target(struct gl_context *ctx, GLenum target)
    106 {
    107    /* Other targets are only supported in desktop OpenGL and OpenGL ES 3.0.
    108     */
    109    if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)
    110        && target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER)
    111       return NULL;
    112 
    113    switch (target) {
    114    case GL_ARRAY_BUFFER_ARB:
    115       return &ctx->Array.ArrayBufferObj;
    116    case GL_ELEMENT_ARRAY_BUFFER_ARB:
    117       return &ctx->Array.VAO->IndexBufferObj;
    118    case GL_PIXEL_PACK_BUFFER_EXT:
    119       return &ctx->Pack.BufferObj;
    120    case GL_PIXEL_UNPACK_BUFFER_EXT:
    121       return &ctx->Unpack.BufferObj;
    122    case GL_COPY_READ_BUFFER:
    123       return &ctx->CopyReadBuffer;
    124    case GL_COPY_WRITE_BUFFER:
    125       return &ctx->CopyWriteBuffer;
    126    case GL_QUERY_BUFFER:
    127       if (_mesa_has_ARB_query_buffer_object(ctx))
    128          return &ctx->QueryBuffer;
    129       break;
    130    case GL_DRAW_INDIRECT_BUFFER:
    131       if ((ctx->API == API_OPENGL_CORE &&
    132            ctx->Extensions.ARB_draw_indirect) ||
    133            _mesa_is_gles31(ctx)) {
    134          return &ctx->DrawIndirectBuffer;
    135       }
    136       break;
    137    case GL_PARAMETER_BUFFER_ARB:
    138       if (_mesa_has_ARB_indirect_parameters(ctx)) {
    139          return &ctx->ParameterBuffer;
    140       }
    141       break;
    142    case GL_DISPATCH_INDIRECT_BUFFER:
    143       if (_mesa_has_compute_shaders(ctx)) {
    144          return &ctx->DispatchIndirectBuffer;
    145       }
    146       break;
    147    case GL_TRANSFORM_FEEDBACK_BUFFER:
    148       if (ctx->Extensions.EXT_transform_feedback) {
    149          return &ctx->TransformFeedback.CurrentBuffer;
    150       }
    151       break;
    152    case GL_TEXTURE_BUFFER:
    153       if (_mesa_has_ARB_texture_buffer_object(ctx) ||
    154           _mesa_has_OES_texture_buffer(ctx)) {
    155          return &ctx->Texture.BufferObject;
    156       }
    157       break;
    158    case GL_UNIFORM_BUFFER:
    159       if (ctx->Extensions.ARB_uniform_buffer_object) {
    160          return &ctx->UniformBuffer;
    161       }
    162       break;
    163    case GL_SHADER_STORAGE_BUFFER:
    164       if (ctx->Extensions.ARB_shader_storage_buffer_object) {
    165          return &ctx->ShaderStorageBuffer;
    166       }
    167       break;
    168    case GL_ATOMIC_COUNTER_BUFFER:
    169       if (ctx->Extensions.ARB_shader_atomic_counters) {
    170          return &ctx->AtomicBuffer;
    171       }
    172       break;
    173    case GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD:
    174       if (ctx->Extensions.AMD_pinned_memory) {
    175          return &ctx->ExternalVirtualMemoryBuffer;
    176       }
    177       break;
    178    default:
    179       return NULL;
    180    }
    181    return NULL;
    182 }
    183 
    184 
    185 /**
    186  * Get the buffer object bound to the specified target in a GL context.
    187  * \param ctx  the GL context
    188  * \param target  the buffer object target to be retrieved.
    189  * \param error  the GL error to record if target is illegal.
    190  * \return   pointer to the buffer object bound to \c target in the
    191  *           specified context or \c NULL if \c target is invalid.
    192  */
    193 static inline struct gl_buffer_object *
    194 get_buffer(struct gl_context *ctx, const char *func, GLenum target,
    195            GLenum error)
    196 {
    197    struct gl_buffer_object **bufObj = get_buffer_target(ctx, target);
    198 
    199    if (!bufObj) {
    200       _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
    201       return NULL;
    202    }
    203 
    204    if (!_mesa_is_bufferobj(*bufObj)) {
    205       _mesa_error(ctx, error, "%s(no buffer bound)", func);
    206       return NULL;
    207    }
    208 
    209    return *bufObj;
    210 }
    211 
    212 
    213 /**
    214  * Convert a GLbitfield describing the mapped buffer access flags
    215  * into one of GL_READ_WRITE, GL_READ_ONLY, or GL_WRITE_ONLY.
    216  */
    217 static GLenum
    218 simplified_access_mode(struct gl_context *ctx, GLbitfield access)
    219 {
    220    const GLbitfield rwFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
    221    if ((access & rwFlags) == rwFlags)
    222       return GL_READ_WRITE;
    223    if ((access & GL_MAP_READ_BIT) == GL_MAP_READ_BIT)
    224       return GL_READ_ONLY;
    225    if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT)
    226       return GL_WRITE_ONLY;
    227 
    228    /* Otherwise, AccessFlags is zero (the default state).
    229     *
    230     * Table 2.6 on page 31 (page 44 of the PDF) of the OpenGL 1.5 spec says:
    231     *
    232     * Name           Type  Initial Value  Legal Values
    233     * ...            ...   ...            ...
    234     * BUFFER_ACCESS  enum  READ_WRITE     READ_ONLY, WRITE_ONLY
    235     *                                     READ_WRITE
    236     *
    237     * However, table 6.8 in the GL_OES_mapbuffer extension says:
    238     *
    239     * Get Value         Type Get Command          Value          Description
    240     * ---------         ---- -----------          -----          -----------
    241     * BUFFER_ACCESS_OES Z1   GetBufferParameteriv WRITE_ONLY_OES buffer map flag
    242     *
    243     * The difference is because GL_OES_mapbuffer only supports mapping buffers
    244     * write-only.
    245     */
    246    assert(access == 0);
    247 
    248    return _mesa_is_gles(ctx) ? GL_WRITE_ONLY : GL_READ_WRITE;
    249 }
    250 
    251 
    252 /**
    253  * Test if the buffer is mapped, and if so, if the mapped range overlaps the
    254  * given range.
    255  * The regions do not overlap if and only if the end of the given
    256  * region is before the mapped region or the start of the given region
    257  * is after the mapped region.
    258  *
    259  * \param obj     Buffer object target on which to operate.
    260  * \param offset  Offset of the first byte of the subdata range.
    261  * \param size    Size, in bytes, of the subdata range.
    262  * \return   true if ranges overlap, false otherwise
    263  *
    264  */
    265 static bool
    266 bufferobj_range_mapped(const struct gl_buffer_object *obj,
    267                        GLintptr offset, GLsizeiptr size)
    268 {
    269    if (_mesa_bufferobj_mapped(obj, MAP_USER)) {
    270       const GLintptr end = offset + size;
    271       const GLintptr mapEnd = obj->Mappings[MAP_USER].Offset +
    272                               obj->Mappings[MAP_USER].Length;
    273 
    274       if (!(end <= obj->Mappings[MAP_USER].Offset || offset >= mapEnd)) {
    275          return true;
    276       }
    277    }
    278    return false;
    279 }
    280 
    281 
    282 /**
    283  * Tests the subdata range parameters and sets the GL error code for
    284  * \c glBufferSubDataARB, \c glGetBufferSubDataARB and
    285  * \c glClearBufferSubData.
    286  *
    287  * \param ctx     GL context.
    288  * \param bufObj  The buffer object.
    289  * \param offset  Offset of the first byte of the subdata range.
    290  * \param size    Size, in bytes, of the subdata range.
    291  * \param mappedRange  If true, checks if an overlapping range is mapped.
    292  *                     If false, checks if buffer is mapped.
    293  * \param caller  Name of calling function for recording errors.
    294  * \return   false if error, true otherwise
    295  *
    296  * \sa glBufferSubDataARB, glGetBufferSubDataARB, glClearBufferSubData
    297  */
    298 static bool
    299 buffer_object_subdata_range_good(struct gl_context *ctx,
    300                                  const struct gl_buffer_object *bufObj,
    301                                  GLintptr offset, GLsizeiptr size,
    302                                  bool mappedRange, const char *caller)
    303 {
    304    if (size < 0) {
    305       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size < 0)", caller);
    306       return false;
    307    }
    308 
    309    if (offset < 0) {
    310       _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset < 0)", caller);
    311       return false;
    312    }
    313 
    314    if (offset + size > bufObj->Size) {
    315       _mesa_error(ctx, GL_INVALID_VALUE,
    316                   "%s(offset %lu + size %lu > buffer size %lu)", caller,
    317                   (unsigned long) offset,
    318                   (unsigned long) size,
    319                   (unsigned long) bufObj->Size);
    320       return false;
    321    }
    322 
    323    if (bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_PERSISTENT_BIT)
    324       return true;
    325 
    326    if (mappedRange) {
    327       if (bufferobj_range_mapped(bufObj, offset, size)) {
    328          _mesa_error(ctx, GL_INVALID_OPERATION,
    329                      "%s(range is mapped without persistent bit)",
    330                      caller);
    331          return false;
    332       }
    333    }
    334    else {
    335       if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
    336          _mesa_error(ctx, GL_INVALID_OPERATION,
    337                      "%s(buffer is mapped without persistent bit)",
    338                      caller);
    339          return false;
    340       }
    341    }
    342 
    343    return true;
    344 }
    345 
    346 
    347 /**
    348  * Test the format and type parameters and set the GL error code for
    349  * \c glClearBufferData and \c glClearBufferSubData.
    350  *
    351  * \param ctx             GL context.
    352  * \param internalformat  Format to which the data is to be converted.
    353  * \param format          Format of the supplied data.
    354  * \param type            Type of the supplied data.
    355  * \param caller          Name of calling function for recording errors.
    356  * \return   If internalformat, format and type are legal the mesa_format
    357  *           corresponding to internalformat, otherwise MESA_FORMAT_NONE.
    358  *
    359  * \sa glClearBufferData and glClearBufferSubData
    360  */
    361 static mesa_format
    362 validate_clear_buffer_format(struct gl_context *ctx,
    363                              GLenum internalformat,
    364                              GLenum format, GLenum type,
    365                              const char *caller)
    366 {
    367    mesa_format mesaFormat;
    368    GLenum errorFormatType;
    369 
    370    mesaFormat = _mesa_validate_texbuffer_format(ctx, internalformat);
    371    if (mesaFormat == MESA_FORMAT_NONE) {
    372       _mesa_error(ctx, GL_INVALID_ENUM,
    373                   "%s(invalid internalformat)", caller);
    374       return MESA_FORMAT_NONE;
    375    }
    376 
    377    /* NOTE: not mentioned in ARB_clear_buffer_object but according to
    378     * EXT_texture_integer there is no conversion between integer and
    379     * non-integer formats
    380    */
    381    if (_mesa_is_enum_format_signed_int(format) !=
    382        _mesa_is_format_integer_color(mesaFormat)) {
    383       _mesa_error(ctx, GL_INVALID_OPERATION,
    384                   "%s(integer vs non-integer)", caller);
    385       return MESA_FORMAT_NONE;
    386    }
    387 
    388    if (!_mesa_is_color_format(format)) {
    389       _mesa_error(ctx, GL_INVALID_ENUM,
    390                   "%s(format is not a color format)", caller);
    391       return MESA_FORMAT_NONE;
    392    }
    393 
    394    errorFormatType = _mesa_error_check_format_and_type(ctx, format, type);
    395    if (errorFormatType != GL_NO_ERROR) {
    396       _mesa_error(ctx, GL_INVALID_ENUM,
    397                   "%s(invalid format or type)", caller);
    398       return MESA_FORMAT_NONE;
    399    }
    400 
    401    return mesaFormat;
    402 }
    403 
    404 
    405 /**
    406  * Convert user-specified clear value to the specified internal format.
    407  *
    408  * \param ctx             GL context.
    409  * \param internalformat  Format to which the data is converted.
    410  * \param clearValue      Points to the converted clear value.
    411  * \param format          Format of the supplied data.
    412  * \param type            Type of the supplied data.
    413  * \param data            Data which is to be converted to internalformat.
    414  * \param caller          Name of calling function for recording errors.
    415  * \return   true if data could be converted, false otherwise.
    416  *
    417  * \sa glClearBufferData, glClearBufferSubData
    418  */
    419 static bool
    420 convert_clear_buffer_data(struct gl_context *ctx,
    421                           mesa_format internalformat,
    422                           GLubyte *clearValue, GLenum format, GLenum type,
    423                           const GLvoid *data, const char *caller)
    424 {
    425    GLenum internalformatBase = _mesa_get_format_base_format(internalformat);
    426 
    427    if (_mesa_texstore(ctx, 1, internalformatBase, internalformat,
    428                       0, &clearValue, 1, 1, 1,
    429                       format, type, data, &ctx->Unpack)) {
    430       return true;
    431    }
    432    else {
    433       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
    434       return false;
    435    }
    436 }
    437 
    438 
    439 /**
    440  * Allocate and initialize a new buffer object.
    441  *
    442  * Default callback for the \c dd_function_table::NewBufferObject() hook.
    443  */
    444 static struct gl_buffer_object *
    445 _mesa_new_buffer_object(struct gl_context *ctx, GLuint name)
    446 {
    447    struct gl_buffer_object *obj = MALLOC_STRUCT(gl_buffer_object);
    448    if (!obj)
    449       return NULL;
    450 
    451    _mesa_initialize_buffer_object(ctx, obj, name);
    452    return obj;
    453 }
    454 
    455 
    456 /**
    457  * Delete a buffer object.
    458  *
    459  * Default callback for the \c dd_function_table::DeleteBuffer() hook.
    460  */
    461 void
    462 _mesa_delete_buffer_object(struct gl_context *ctx,
    463                            struct gl_buffer_object *bufObj)
    464 {
    465    (void) ctx;
    466 
    467    vbo_delete_minmax_cache(bufObj);
    468    _mesa_align_free(bufObj->Data);
    469 
    470    /* assign strange values here to help w/ debugging */
    471    bufObj->RefCount = -1000;
    472    bufObj->Name = ~0;
    473 
    474    simple_mtx_destroy(&bufObj->Mutex);
    475    free(bufObj->Label);
    476    free(bufObj);
    477 }
    478 
    479 
    480 
    481 /**
    482  * Set ptr to bufObj w/ reference counting.
    483  * This is normally only called from the _mesa_reference_buffer_object() macro
    484  * when there's a real pointer change.
    485  */
    486 void
    487 _mesa_reference_buffer_object_(struct gl_context *ctx,
    488                                struct gl_buffer_object **ptr,
    489                                struct gl_buffer_object *bufObj)
    490 {
    491    if (*ptr) {
    492       /* Unreference the old buffer */
    493       GLboolean deleteFlag = GL_FALSE;
    494       struct gl_buffer_object *oldObj = *ptr;
    495 
    496       simple_mtx_lock(&oldObj->Mutex);
    497       assert(oldObj->RefCount > 0);
    498       oldObj->RefCount--;
    499       deleteFlag = (oldObj->RefCount == 0);
    500       simple_mtx_unlock(&oldObj->Mutex);
    501 
    502       if (deleteFlag) {
    503 	 assert(ctx->Driver.DeleteBuffer);
    504          ctx->Driver.DeleteBuffer(ctx, oldObj);
    505       }
    506 
    507       *ptr = NULL;
    508    }
    509    assert(!*ptr);
    510 
    511    if (bufObj) {
    512       /* reference new buffer */
    513       simple_mtx_lock(&bufObj->Mutex);
    514       assert(bufObj->RefCount > 0);
    515 
    516       bufObj->RefCount++;
    517       *ptr = bufObj;
    518       simple_mtx_unlock(&bufObj->Mutex);
    519    }
    520 }
    521 
    522 
    523 /**
    524  * Get the value of MESA_NO_MINMAX_CACHE.
    525  */
    526 static bool
    527 get_no_minmax_cache()
    528 {
    529    static bool read = false;
    530    static bool disable = false;
    531 
    532    if (!read) {
    533       disable = env_var_as_boolean("MESA_NO_MINMAX_CACHE", false);
    534       read = true;
    535    }
    536 
    537    return disable;
    538 }
    539 
    540 
    541 /**
    542  * Initialize a buffer object to default values.
    543  */
    544 void
    545 _mesa_initialize_buffer_object(struct gl_context *ctx,
    546                                struct gl_buffer_object *obj,
    547                                GLuint name)
    548 {
    549    memset(obj, 0, sizeof(struct gl_buffer_object));
    550    simple_mtx_init(&obj->Mutex, mtx_plain);
    551    obj->RefCount = 1;
    552    obj->Name = name;
    553    obj->Usage = GL_STATIC_DRAW_ARB;
    554 
    555    if (get_no_minmax_cache())
    556       obj->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE;
    557 }
    558 
    559 
    560 
    561 /**
    562  * Callback called from _mesa_HashWalk()
    563  */
    564 static void
    565 count_buffer_size(GLuint key, void *data, void *userData)
    566 {
    567    const struct gl_buffer_object *bufObj =
    568       (const struct gl_buffer_object *) data;
    569    GLuint *total = (GLuint *) userData;
    570 
    571    (void) key;
    572    *total = *total + bufObj->Size;
    573 }
    574 
    575 
    576 /**
    577  * Compute total size (in bytes) of all buffer objects for the given context.
    578  * For debugging purposes.
    579  */
    580 GLuint
    581 _mesa_total_buffer_object_memory(struct gl_context *ctx)
    582 {
    583    GLuint total = 0;
    584 
    585    _mesa_HashWalk(ctx->Shared->BufferObjects, count_buffer_size, &total);
    586 
    587    return total;
    588 }
    589 
    590 
    591 /**
    592  * Allocate space for and store data in a buffer object.  Any data that was
    593  * previously stored in the buffer object is lost.  If \c data is \c NULL,
    594  * memory will be allocated, but no copy will occur.
    595  *
    596  * This is the default callback for \c dd_function_table::BufferData()
    597  * Note that all GL error checking will have been done already.
    598  *
    599  * \param ctx     GL context.
    600  * \param target  Buffer object target on which to operate.
    601  * \param size    Size, in bytes, of the new data store.
    602  * \param data    Pointer to the data to store in the buffer object.  This
    603  *                pointer may be \c NULL.
    604  * \param usage   Hints about how the data will be used.
    605  * \param bufObj  Object to be used.
    606  *
    607  * \return GL_TRUE for success, GL_FALSE for failure
    608  * \sa glBufferDataARB, dd_function_table::BufferData.
    609  */
    610 static GLboolean
    611 buffer_data_fallback(struct gl_context *ctx, GLenum target, GLsizeiptr size,
    612                      const GLvoid *data, GLenum usage, GLenum storageFlags,
    613                      struct gl_buffer_object *bufObj)
    614 {
    615    void * new_data;
    616 
    617    (void) target;
    618 
    619    _mesa_align_free( bufObj->Data );
    620 
    621    new_data = _mesa_align_malloc( size, ctx->Const.MinMapBufferAlignment );
    622    if (new_data) {
    623       bufObj->Data = (GLubyte *) new_data;
    624       bufObj->Size = size;
    625       bufObj->Usage = usage;
    626       bufObj->StorageFlags = storageFlags;
    627 
    628       if (data) {
    629 	 memcpy( bufObj->Data, data, size );
    630       }
    631 
    632       return GL_TRUE;
    633    }
    634    else {
    635       return GL_FALSE;
    636    }
    637 }
    638 
    639 
    640 /**
    641  * Replace data in a subrange of buffer object.  If the data range
    642  * specified by \c size + \c offset extends beyond the end of the buffer or
    643  * if \c data is \c NULL, no copy is performed.
    644  *
    645  * This is the default callback for \c dd_function_table::BufferSubData()
    646  * Note that all GL error checking will have been done already.
    647  *
    648  * \param ctx     GL context.
    649  * \param offset  Offset of the first byte to be modified.
    650  * \param size    Size, in bytes, of the data range.
    651  * \param data    Pointer to the data to store in the buffer object.
    652  * \param bufObj  Object to be used.
    653  *
    654  * \sa glBufferSubDataARB, dd_function_table::BufferSubData.
    655  */
    656 static void
    657 buffer_sub_data_fallback(struct gl_context *ctx, GLintptr offset,
    658                          GLsizeiptr size, const GLvoid *data,
    659                          struct gl_buffer_object *bufObj)
    660 {
    661    (void) ctx;
    662 
    663    /* this should have been caught in _mesa_BufferSubData() */
    664    assert(size + offset <= bufObj->Size);
    665 
    666    if (bufObj->Data) {
    667       memcpy( (GLubyte *) bufObj->Data + offset, data, size );
    668    }
    669 }
    670 
    671 
    672 /**
    673  * Retrieve data from a subrange of buffer object.  If the data range
    674  * specified by \c size + \c offset extends beyond the end of the buffer or
    675  * if \c data is \c NULL, no copy is performed.
    676  *
    677  * This is the default callback for \c dd_function_table::GetBufferSubData()
    678  * Note that all GL error checking will have been done already.
    679  *
    680  * \param ctx     GL context.
    681  * \param target  Buffer object target on which to operate.
    682  * \param offset  Offset of the first byte to be fetched.
    683  * \param size    Size, in bytes, of the data range.
    684  * \param data    Destination for data
    685  * \param bufObj  Object to be used.
    686  *
    687  * \sa glBufferGetSubDataARB, dd_function_table::GetBufferSubData.
    688  */
    689 static void
    690 buffer_get_subdata(struct gl_context *ctx, GLintptrARB offset,
    691                    GLsizeiptrARB size, GLvoid *data,
    692                    struct gl_buffer_object *bufObj )
    693 {
    694    (void) ctx;
    695 
    696    if (bufObj->Data && ((GLsizeiptrARB) (size + offset) <= bufObj->Size)) {
    697       memcpy( data, (GLubyte *) bufObj->Data + offset, size );
    698    }
    699 }
    700 
    701 
    702 /**
    703  * Clear a subrange of the buffer object with copies of the supplied data.
    704  * If data is NULL the buffer is filled with zeros.
    705  *
    706  * This is the default callback for \c dd_function_table::ClearBufferSubData()
    707  * Note that all GL error checking will have been done already.
    708  *
    709  * \param ctx             GL context.
    710  * \param offset          Offset of the first byte to be cleared.
    711  * \param size            Size, in bytes, of the to be cleared range.
    712  * \param clearValue      Source of the data.
    713  * \param clearValueSize  Size, in bytes, of the supplied data.
    714  * \param bufObj          Object to be cleared.
    715  *
    716  * \sa glClearBufferSubData, glClearBufferData and
    717  * dd_function_table::ClearBufferSubData.
    718  */
    719 void
    720 _mesa_ClearBufferSubData_sw(struct gl_context *ctx,
    721                             GLintptr offset, GLsizeiptr size,
    722                             const GLvoid *clearValue,
    723                             GLsizeiptr clearValueSize,
    724                             struct gl_buffer_object *bufObj)
    725 {
    726    GLsizeiptr i;
    727    GLubyte *dest;
    728 
    729    assert(ctx->Driver.MapBufferRange);
    730    dest = ctx->Driver.MapBufferRange(ctx, offset, size,
    731                                      GL_MAP_WRITE_BIT |
    732                                      GL_MAP_INVALIDATE_RANGE_BIT,
    733                                      bufObj, MAP_INTERNAL);
    734 
    735    if (!dest) {
    736       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data");
    737       return;
    738    }
    739 
    740    if (clearValue == NULL) {
    741       /* Clear with zeros, per the spec */
    742       memset(dest, 0, size);
    743       ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
    744       return;
    745    }
    746 
    747    for (i = 0; i < size/clearValueSize; ++i) {
    748       memcpy(dest, clearValue, clearValueSize);
    749       dest += clearValueSize;
    750    }
    751 
    752    ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL);
    753 }
    754 
    755 
    756 /**
    757  * Default fallback for \c dd_function_table::MapBufferRange().
    758  * Called via glMapBufferRange().
    759  */
    760 static void *
    761 map_buffer_range_fallback(struct gl_context *ctx, GLintptr offset,
    762                           GLsizeiptr length, GLbitfield access,
    763                           struct gl_buffer_object *bufObj,
    764                           gl_map_buffer_index index)
    765 {
    766    (void) ctx;
    767    assert(!_mesa_bufferobj_mapped(bufObj, index));
    768    /* Just return a direct pointer to the data */
    769    bufObj->Mappings[index].Pointer = bufObj->Data + offset;
    770    bufObj->Mappings[index].Length = length;
    771    bufObj->Mappings[index].Offset = offset;
    772    bufObj->Mappings[index].AccessFlags = access;
    773    return bufObj->Mappings[index].Pointer;
    774 }
    775 
    776 
    777 /**
    778  * Default fallback for \c dd_function_table::FlushMappedBufferRange().
    779  * Called via glFlushMappedBufferRange().
    780  */
    781 static void
    782 flush_mapped_buffer_range_fallback(struct gl_context *ctx,
    783                                    GLintptr offset, GLsizeiptr length,
    784                                    struct gl_buffer_object *obj,
    785                                    gl_map_buffer_index index)
    786 {
    787    (void) ctx;
    788    (void) offset;
    789    (void) length;
    790    (void) obj;
    791    (void) index;
    792    /* no-op */
    793 }
    794 
    795 
    796 /**
    797  * Default callback for \c dd_function_table::UnmapBuffer().
    798  *
    799  * The input parameters will have been already tested for errors.
    800  *
    801  * \sa glUnmapBufferARB, dd_function_table::UnmapBuffer
    802  */
    803 static GLboolean
    804 unmap_buffer_fallback(struct gl_context *ctx, struct gl_buffer_object *bufObj,
    805                       gl_map_buffer_index index)
    806 {
    807    (void) ctx;
    808    /* XXX we might assert here that bufObj->Pointer is non-null */
    809    bufObj->Mappings[index].Pointer = NULL;
    810    bufObj->Mappings[index].Length = 0;
    811    bufObj->Mappings[index].Offset = 0;
    812    bufObj->Mappings[index].AccessFlags = 0x0;
    813    return GL_TRUE;
    814 }
    815 
    816 
    817 /**
    818  * Default fallback for \c dd_function_table::CopyBufferSubData().
    819  * Called via glCopyBufferSubData().
    820  */
    821 static void
    822 copy_buffer_sub_data_fallback(struct gl_context *ctx,
    823                               struct gl_buffer_object *src,
    824                               struct gl_buffer_object *dst,
    825                               GLintptr readOffset, GLintptr writeOffset,
    826                               GLsizeiptr size)
    827 {
    828    GLubyte *srcPtr, *dstPtr;
    829 
    830    if (src == dst) {
    831       srcPtr = dstPtr = ctx->Driver.MapBufferRange(ctx, 0, src->Size,
    832 						   GL_MAP_READ_BIT |
    833 						   GL_MAP_WRITE_BIT, src,
    834                                                    MAP_INTERNAL);
    835 
    836       if (!srcPtr)
    837 	 return;
    838 
    839       srcPtr += readOffset;
    840       dstPtr += writeOffset;
    841    } else {
    842       srcPtr = ctx->Driver.MapBufferRange(ctx, readOffset, size,
    843 					  GL_MAP_READ_BIT, src,
    844                                           MAP_INTERNAL);
    845       dstPtr = ctx->Driver.MapBufferRange(ctx, writeOffset, size,
    846 					  (GL_MAP_WRITE_BIT |
    847 					   GL_MAP_INVALIDATE_RANGE_BIT), dst,
    848                                           MAP_INTERNAL);
    849    }
    850 
    851    /* Note: the src and dst regions will never overlap.  Trying to do so
    852     * would generate GL_INVALID_VALUE earlier.
    853     */
    854    if (srcPtr && dstPtr)
    855       memcpy(dstPtr, srcPtr, size);
    856 
    857    ctx->Driver.UnmapBuffer(ctx, src, MAP_INTERNAL);
    858    if (dst != src)
    859       ctx->Driver.UnmapBuffer(ctx, dst, MAP_INTERNAL);
    860 }
    861 
    862 
    863 
    864 /**
    865  * Initialize the state associated with buffer objects
    866  */
    867 void
    868 _mesa_init_buffer_objects( struct gl_context *ctx )
    869 {
    870    GLuint i;
    871 
    872    memset(&DummyBufferObject, 0, sizeof(DummyBufferObject));
    873    simple_mtx_init(&DummyBufferObject.Mutex, mtx_plain);
    874    DummyBufferObject.RefCount = 1000*1000*1000; /* never delete */
    875 
    876    _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj,
    877                                  ctx->Shared->NullBufferObj);
    878 
    879    _mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer,
    880                                  ctx->Shared->NullBufferObj);
    881    _mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer,
    882                                  ctx->Shared->NullBufferObj);
    883 
    884    _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer,
    885 				 ctx->Shared->NullBufferObj);
    886 
    887    _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer,
    888                                  ctx->Shared->NullBufferObj);
    889 
    890    _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer,
    891 				 ctx->Shared->NullBufferObj);
    892 
    893    _mesa_reference_buffer_object(ctx, &ctx->DrawIndirectBuffer,
    894 				 ctx->Shared->NullBufferObj);
    895 
    896    _mesa_reference_buffer_object(ctx, &ctx->ParameterBuffer,
    897 				 ctx->Shared->NullBufferObj);
    898 
    899    _mesa_reference_buffer_object(ctx, &ctx->DispatchIndirectBuffer,
    900 				 ctx->Shared->NullBufferObj);
    901 
    902    _mesa_reference_buffer_object(ctx, &ctx->QueryBuffer,
    903                                  ctx->Shared->NullBufferObj);
    904 
    905    for (i = 0; i < MAX_COMBINED_UNIFORM_BUFFERS; i++) {
    906       _mesa_reference_buffer_object(ctx,
    907 				    &ctx->UniformBufferBindings[i].BufferObject,
    908 				    ctx->Shared->NullBufferObj);
    909       ctx->UniformBufferBindings[i].Offset = -1;
    910       ctx->UniformBufferBindings[i].Size = -1;
    911    }
    912 
    913    for (i = 0; i < MAX_COMBINED_SHADER_STORAGE_BUFFERS; i++) {
    914       _mesa_reference_buffer_object(ctx,
    915                                     &ctx->ShaderStorageBufferBindings[i].BufferObject,
    916                                     ctx->Shared->NullBufferObj);
    917       ctx->ShaderStorageBufferBindings[i].Offset = -1;
    918       ctx->ShaderStorageBufferBindings[i].Size = -1;
    919    }
    920 
    921    for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) {
    922       _mesa_reference_buffer_object(ctx,
    923 				    &ctx->AtomicBufferBindings[i].BufferObject,
    924 				    ctx->Shared->NullBufferObj);
    925       ctx->AtomicBufferBindings[i].Offset = 0;
    926       ctx->AtomicBufferBindings[i].Size = 0;
    927    }
    928 }
    929 
    930 
    931 void
    932 _mesa_free_buffer_objects( struct gl_context *ctx )
    933 {
    934    GLuint i;
    935 
    936    _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
    937 
    938    _mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer, NULL);
    939    _mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer, NULL);
    940 
    941    _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, NULL);
    942 
    943    _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, NULL);
    944 
    945    _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, NULL);
    946 
    947    _mesa_reference_buffer_object(ctx, &ctx->DrawIndirectBuffer, NULL);
    948 
    949    _mesa_reference_buffer_object(ctx, &ctx->ParameterBuffer, NULL);
    950 
    951    _mesa_reference_buffer_object(ctx, &ctx->DispatchIndirectBuffer, NULL);
    952 
    953    _mesa_reference_buffer_object(ctx, &ctx->QueryBuffer, NULL);
    954 
    955    for (i = 0; i < MAX_COMBINED_UNIFORM_BUFFERS; i++) {
    956       _mesa_reference_buffer_object(ctx,
    957 				    &ctx->UniformBufferBindings[i].BufferObject,
    958 				    NULL);
    959    }
    960 
    961    for (i = 0; i < MAX_COMBINED_SHADER_STORAGE_BUFFERS; i++) {
    962       _mesa_reference_buffer_object(ctx,
    963                                     &ctx->ShaderStorageBufferBindings[i].BufferObject,
    964                                     NULL);
    965    }
    966 
    967    for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) {
    968       _mesa_reference_buffer_object(ctx,
    969 				    &ctx->AtomicBufferBindings[i].BufferObject,
    970 				    NULL);
    971    }
    972 
    973 }
    974 
    975 bool
    976 _mesa_handle_bind_buffer_gen(struct gl_context *ctx,
    977                              GLuint buffer,
    978                              struct gl_buffer_object **buf_handle,
    979                              const char *caller)
    980 {
    981    struct gl_buffer_object *buf = *buf_handle;
    982 
    983    if (!buf && (ctx->API == API_OPENGL_CORE)) {
    984       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller);
    985       return false;
    986    }
    987 
    988    if (!buf || buf == &DummyBufferObject) {
    989       /* If this is a new buffer object id, or one which was generated but
    990        * never used before, allocate a buffer object now.
    991        */
    992       buf = ctx->Driver.NewBufferObject(ctx, buffer);
    993       if (!buf) {
    994 	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
    995 	 return false;
    996       }
    997       _mesa_HashInsert(ctx->Shared->BufferObjects, buffer, buf);
    998       *buf_handle = buf;
    999    }
   1000 
   1001    return true;
   1002 }
   1003 
   1004 /**
   1005  * Bind the specified target to buffer for the specified context.
   1006  * Called by glBindBuffer() and other functions.
   1007  */
   1008 static void
   1009 bind_buffer_object(struct gl_context *ctx,
   1010                    struct gl_buffer_object **bindTarget, GLuint buffer)
   1011 {
   1012    struct gl_buffer_object *oldBufObj;
   1013    struct gl_buffer_object *newBufObj = NULL;
   1014 
   1015    assert(bindTarget);
   1016 
   1017    /* Get pointer to old buffer object (to be unbound) */
   1018    oldBufObj = *bindTarget;
   1019    if (oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending)
   1020       return;   /* rebinding the same buffer object- no change */
   1021 
   1022    /*
   1023     * Get pointer to new buffer object (newBufObj)
   1024     */
   1025    if (buffer == 0) {
   1026       /* The spec says there's not a buffer object named 0, but we use
   1027        * one internally because it simplifies things.
   1028        */
   1029       newBufObj = ctx->Shared->NullBufferObj;
   1030    }
   1031    else {
   1032       /* non-default buffer object */
   1033       newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
   1034       if (!_mesa_handle_bind_buffer_gen(ctx, buffer,
   1035                                         &newBufObj, "glBindBuffer"))
   1036          return;
   1037    }
   1038 
   1039    /* record usage history */
   1040    if (bindTarget == &ctx->Pack.BufferObj) {
   1041       newBufObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER;
   1042    }
   1043 
   1044    /* bind new buffer */
   1045    _mesa_reference_buffer_object(ctx, bindTarget, newBufObj);
   1046 }
   1047 
   1048 
   1049 /**
   1050  * Update the default buffer objects in the given context to reference those
   1051  * specified in the shared state and release those referencing the old
   1052  * shared state.
   1053  */
   1054 void
   1055 _mesa_update_default_objects_buffer_objects(struct gl_context *ctx)
   1056 {
   1057    /* Bind the NullBufferObj to remove references to those
   1058     * in the shared context hash table.
   1059     */
   1060    bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0);
   1061    bind_buffer_object(ctx, &ctx->Array.VAO->IndexBufferObj, 0);
   1062    bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0);
   1063    bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0);
   1064 }
   1065 
   1066 
   1067 
   1068 /**
   1069  * Return the gl_buffer_object for the given ID.
   1070  * Always return NULL for ID 0.
   1071  */
   1072 struct gl_buffer_object *
   1073 _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer)
   1074 {
   1075    if (buffer == 0)
   1076       return NULL;
   1077    else
   1078       return (struct gl_buffer_object *)
   1079          _mesa_HashLookup(ctx->Shared->BufferObjects, buffer);
   1080 }
   1081 
   1082 
   1083 struct gl_buffer_object *
   1084 _mesa_lookup_bufferobj_locked(struct gl_context *ctx, GLuint buffer)
   1085 {
   1086    if (buffer == 0)
   1087       return NULL;
   1088    else
   1089       return (struct gl_buffer_object *)
   1090          _mesa_HashLookupLocked(ctx->Shared->BufferObjects, buffer);
   1091 }
   1092 
   1093 /**
   1094  * A convenience function for direct state access functions that throws
   1095  * GL_INVALID_OPERATION if buffer is not the name of an existing
   1096  * buffer object.
   1097  */
   1098 struct gl_buffer_object *
   1099 _mesa_lookup_bufferobj_err(struct gl_context *ctx, GLuint buffer,
   1100                            const char *caller)
   1101 {
   1102    struct gl_buffer_object *bufObj;
   1103 
   1104    bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   1105    if (!bufObj || bufObj == &DummyBufferObject) {
   1106       _mesa_error(ctx, GL_INVALID_OPERATION,
   1107                   "%s(non-existent buffer object %u)", caller, buffer);
   1108       return NULL;
   1109    }
   1110 
   1111    return bufObj;
   1112 }
   1113 
   1114 
   1115 /**
   1116  * Look up a buffer object for a multi-bind function.
   1117  *
   1118  * Unlike _mesa_lookup_bufferobj(), this function also takes care
   1119  * of generating an error if the buffer ID is not zero or the name
   1120  * of an existing buffer object.
   1121  *
   1122  * If the buffer ID refers to an existing buffer object, a pointer
   1123  * to the buffer object is returned.  If the ID is zero, a pointer
   1124  * to the shared NullBufferObj is returned.  If the ID is not zero
   1125  * and does not refer to a valid buffer object, this function
   1126  * returns NULL.
   1127  *
   1128  * This function assumes that the caller has already locked the
   1129  * hash table mutex by calling
   1130  * _mesa_HashLockMutex(ctx->Shared->BufferObjects).
   1131  */
   1132 struct gl_buffer_object *
   1133 _mesa_multi_bind_lookup_bufferobj(struct gl_context *ctx,
   1134                                   const GLuint *buffers,
   1135                                   GLuint index, const char *caller)
   1136 {
   1137    struct gl_buffer_object *bufObj;
   1138 
   1139    if (buffers[index] != 0) {
   1140       bufObj = _mesa_lookup_bufferobj_locked(ctx, buffers[index]);
   1141 
   1142       /* The multi-bind functions don't create the buffer objects
   1143          when they don't exist. */
   1144       if (bufObj == &DummyBufferObject)
   1145          bufObj = NULL;
   1146    } else
   1147       bufObj = ctx->Shared->NullBufferObj;
   1148 
   1149    if (!bufObj) {
   1150       /* The ARB_multi_bind spec says:
   1151        *
   1152        *    "An INVALID_OPERATION error is generated if any value
   1153        *     in <buffers> is not zero or the name of an existing
   1154        *     buffer object (per binding)."
   1155        */
   1156       _mesa_error(ctx, GL_INVALID_OPERATION,
   1157                   "%s(buffers[%u]=%u is not zero or the name "
   1158                   "of an existing buffer object)",
   1159                   caller, index, buffers[index]);
   1160    }
   1161 
   1162    return bufObj;
   1163 }
   1164 
   1165 
   1166 /**
   1167  * If *ptr points to obj, set ptr = the Null/default buffer object.
   1168  * This is a helper for buffer object deletion.
   1169  * The GL spec says that deleting a buffer object causes it to get
   1170  * unbound from all arrays in the current context.
   1171  */
   1172 static void
   1173 unbind(struct gl_context *ctx,
   1174        struct gl_vertex_array_object *vao, unsigned index,
   1175        struct gl_buffer_object *obj)
   1176 {
   1177    if (vao->BufferBinding[index].BufferObj == obj) {
   1178       _mesa_bind_vertex_buffer(ctx, vao, index, ctx->Shared->NullBufferObj,
   1179                                vao->BufferBinding[index].Offset,
   1180                                vao->BufferBinding[index].Stride);
   1181    }
   1182 }
   1183 
   1184 
   1185 /**
   1186  * Plug default/fallback buffer object functions into the device
   1187  * driver hooks.
   1188  */
   1189 void
   1190 _mesa_init_buffer_object_functions(struct dd_function_table *driver)
   1191 {
   1192    /* GL_ARB_vertex/pixel_buffer_object */
   1193    driver->NewBufferObject = _mesa_new_buffer_object;
   1194    driver->DeleteBuffer = _mesa_delete_buffer_object;
   1195    driver->BufferData = buffer_data_fallback;
   1196    driver->BufferSubData = buffer_sub_data_fallback;
   1197    driver->GetBufferSubData = buffer_get_subdata;
   1198    driver->UnmapBuffer = unmap_buffer_fallback;
   1199 
   1200    /* GL_ARB_clear_buffer_object */
   1201    driver->ClearBufferSubData = _mesa_ClearBufferSubData_sw;
   1202 
   1203    /* GL_ARB_map_buffer_range */
   1204    driver->MapBufferRange = map_buffer_range_fallback;
   1205    driver->FlushMappedBufferRange = flush_mapped_buffer_range_fallback;
   1206 
   1207    /* GL_ARB_copy_buffer */
   1208    driver->CopyBufferSubData = copy_buffer_sub_data_fallback;
   1209 }
   1210 
   1211 
   1212 void
   1213 _mesa_buffer_unmap_all_mappings(struct gl_context *ctx,
   1214                                 struct gl_buffer_object *bufObj)
   1215 {
   1216    for (int i = 0; i < MAP_COUNT; i++) {
   1217       if (_mesa_bufferobj_mapped(bufObj, i)) {
   1218          ctx->Driver.UnmapBuffer(ctx, bufObj, i);
   1219          assert(bufObj->Mappings[i].Pointer == NULL);
   1220          bufObj->Mappings[i].AccessFlags = 0;
   1221       }
   1222    }
   1223 }
   1224 
   1225 
   1226 /**********************************************************************/
   1227 /* API Functions                                                      */
   1228 /**********************************************************************/
   1229 
   1230 void GLAPIENTRY
   1231 _mesa_BindBuffer_no_error(GLenum target, GLuint buffer)
   1232 {
   1233    GET_CURRENT_CONTEXT(ctx);
   1234 
   1235    struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target);
   1236    bind_buffer_object(ctx, bindTarget, buffer);
   1237 }
   1238 
   1239 
   1240 void GLAPIENTRY
   1241 _mesa_BindBuffer(GLenum target, GLuint buffer)
   1242 {
   1243    GET_CURRENT_CONTEXT(ctx);
   1244 
   1245    if (MESA_VERBOSE & VERBOSE_API) {
   1246       _mesa_debug(ctx, "glBindBuffer(%s, %u)\n",
   1247                   _mesa_enum_to_string(target), buffer);
   1248    }
   1249 
   1250    struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target);
   1251    if (!bindTarget) {
   1252       _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target %s)",
   1253                   _mesa_enum_to_string(target));
   1254       return;
   1255    }
   1256 
   1257    bind_buffer_object(ctx, bindTarget, buffer);
   1258 }
   1259 
   1260 /**
   1261  * Binds a buffer object to a binding point.
   1262  *
   1263  * The caller is responsible for validating the offset,
   1264  * flushing the vertices and updating NewDriverState.
   1265  */
   1266 static void
   1267 set_buffer_binding(struct gl_context *ctx,
   1268                    struct gl_buffer_binding *binding,
   1269                    struct gl_buffer_object *bufObj,
   1270                    GLintptr offset,
   1271                    GLsizeiptr size,
   1272                    bool autoSize, gl_buffer_usage usage)
   1273 {
   1274    _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
   1275 
   1276    binding->Offset = offset;
   1277    binding->Size = size;
   1278    binding->AutomaticSize = autoSize;
   1279 
   1280    /* If this is a real buffer object, mark it has having been used
   1281     * at some point as an atomic counter buffer.
   1282     */
   1283    if (size >= 0)
   1284       bufObj->UsageHistory |= usage;
   1285 }
   1286 
   1287 static void
   1288 set_buffer_multi_binding(struct gl_context *ctx,
   1289                          const GLuint *buffers,
   1290                          int idx,
   1291                          const char *caller,
   1292                          struct gl_buffer_binding *binding,
   1293                          GLintptr offset,
   1294                          GLsizeiptr size,
   1295                          bool range,
   1296                          gl_buffer_usage usage)
   1297 {
   1298    struct gl_buffer_object *bufObj;
   1299    if (binding->BufferObject && binding->BufferObject->Name == buffers[idx])
   1300       bufObj = binding->BufferObject;
   1301    else
   1302       bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, idx, caller);
   1303 
   1304    if (bufObj) {
   1305       if (bufObj == ctx->Shared->NullBufferObj)
   1306          set_buffer_binding(ctx, binding, bufObj, -1, -1, !range, usage);
   1307       else
   1308          set_buffer_binding(ctx, binding, bufObj, offset, size, !range, usage);
   1309    }
   1310 }
   1311 
   1312 static void
   1313 bind_buffer(struct gl_context *ctx,
   1314             struct gl_buffer_binding *binding,
   1315             struct gl_buffer_object *bufObj,
   1316             GLintptr offset,
   1317             GLsizeiptr size,
   1318             GLboolean autoSize,
   1319             uint64_t driver_state,
   1320             gl_buffer_usage usage)
   1321 {
   1322    if (binding->BufferObject == bufObj &&
   1323        binding->Offset == offset &&
   1324        binding->Size == size &&
   1325        binding->AutomaticSize == autoSize) {
   1326       return;
   1327    }
   1328 
   1329    FLUSH_VERTICES(ctx, 0);
   1330    ctx->NewDriverState |= driver_state;
   1331 
   1332    set_buffer_binding(ctx, binding, bufObj, offset, size, autoSize, usage);
   1333 }
   1334 
   1335 /**
   1336  * Binds a buffer object to a uniform buffer binding point.
   1337  *
   1338  * Unlike set_buffer_binding(), this function also flushes vertices
   1339  * and updates NewDriverState.  It also checks if the binding
   1340  * has actually changed before updating it.
   1341  */
   1342 static void
   1343 bind_uniform_buffer(struct gl_context *ctx,
   1344                     GLuint index,
   1345                     struct gl_buffer_object *bufObj,
   1346                     GLintptr offset,
   1347                     GLsizeiptr size,
   1348                     GLboolean autoSize)
   1349 {
   1350    bind_buffer(ctx, &ctx->UniformBufferBindings[index],
   1351                bufObj, offset, size, autoSize,
   1352                ctx->DriverFlags.NewUniformBuffer,
   1353                USAGE_UNIFORM_BUFFER);
   1354 }
   1355 
   1356 /**
   1357  * Binds a buffer object to a shader storage buffer binding point.
   1358  *
   1359  * Unlike set_ssbo_binding(), this function also flushes vertices
   1360  * and updates NewDriverState.  It also checks if the binding
   1361  * has actually changed before updating it.
   1362  */
   1363 static void
   1364 bind_shader_storage_buffer(struct gl_context *ctx,
   1365                            GLuint index,
   1366                            struct gl_buffer_object *bufObj,
   1367                            GLintptr offset,
   1368                            GLsizeiptr size,
   1369                            GLboolean autoSize)
   1370 {
   1371    bind_buffer(ctx, &ctx->ShaderStorageBufferBindings[index],
   1372                bufObj, offset, size, autoSize,
   1373                ctx->DriverFlags.NewShaderStorageBuffer,
   1374                USAGE_SHADER_STORAGE_BUFFER);
   1375 }
   1376 
   1377 /**
   1378  * Binds a buffer object to an atomic buffer binding point.
   1379  *
   1380  * Unlike set_atomic_binding(), this function also flushes vertices
   1381  * and updates NewDriverState.  It also checks if the binding
   1382  * has actually changed before updating it.
   1383  */
   1384 static void
   1385 bind_atomic_buffer(struct gl_context *ctx, unsigned index,
   1386                    struct gl_buffer_object *bufObj, GLintptr offset,
   1387                    GLsizeiptr size, GLboolean autoSize)
   1388 {
   1389    bind_buffer(ctx, &ctx->AtomicBufferBindings[index],
   1390                bufObj, offset, size, autoSize,
   1391                ctx->DriverFlags.NewAtomicBuffer,
   1392                USAGE_ATOMIC_COUNTER_BUFFER);
   1393 }
   1394 
   1395 /**
   1396  * Bind a buffer object to a uniform block binding point.
   1397  * As above, but offset = 0.
   1398  */
   1399 static void
   1400 bind_buffer_base_uniform_buffer(struct gl_context *ctx,
   1401 				GLuint index,
   1402 				struct gl_buffer_object *bufObj)
   1403 {
   1404    if (index >= ctx->Const.MaxUniformBufferBindings) {
   1405       _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
   1406       return;
   1407    }
   1408 
   1409    _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, bufObj);
   1410 
   1411    if (bufObj == ctx->Shared->NullBufferObj)
   1412       bind_uniform_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
   1413    else
   1414       bind_uniform_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
   1415 }
   1416 
   1417 /**
   1418  * Bind a buffer object to a shader storage block binding point.
   1419  * As above, but offset = 0.
   1420  */
   1421 static void
   1422 bind_buffer_base_shader_storage_buffer(struct gl_context *ctx,
   1423                                        GLuint index,
   1424                                        struct gl_buffer_object *bufObj)
   1425 {
   1426    if (index >= ctx->Const.MaxShaderStorageBufferBindings) {
   1427       _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
   1428       return;
   1429    }
   1430 
   1431    _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, bufObj);
   1432 
   1433    if (bufObj == ctx->Shared->NullBufferObj)
   1434       bind_shader_storage_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
   1435    else
   1436       bind_shader_storage_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
   1437 }
   1438 
   1439 /**
   1440  * Bind a buffer object to a shader storage block binding point.
   1441  * As above, but offset = 0.
   1442  */
   1443 static void
   1444 bind_buffer_base_atomic_buffer(struct gl_context *ctx,
   1445                                GLuint index,
   1446                                struct gl_buffer_object *bufObj)
   1447 {
   1448    if (index >= ctx->Const.MaxAtomicBufferBindings) {
   1449       _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
   1450       return;
   1451    }
   1452 
   1453    _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
   1454 
   1455    if (bufObj == ctx->Shared->NullBufferObj)
   1456       bind_atomic_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
   1457    else
   1458       bind_atomic_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
   1459 }
   1460 
   1461 /**
   1462  * Delete a set of buffer objects.
   1463  *
   1464  * \param n      Number of buffer objects to delete.
   1465  * \param ids    Array of \c n buffer object IDs.
   1466  */
   1467 static void
   1468 delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids)
   1469 {
   1470    FLUSH_VERTICES(ctx, 0);
   1471 
   1472    _mesa_HashLockMutex(ctx->Shared->BufferObjects);
   1473 
   1474    for (GLsizei i = 0; i < n; i++) {
   1475       struct gl_buffer_object *bufObj =
   1476          _mesa_lookup_bufferobj_locked(ctx, ids[i]);
   1477       if (bufObj) {
   1478          struct gl_vertex_array_object *vao = ctx->Array.VAO;
   1479          GLuint j;
   1480 
   1481          assert(bufObj->Name == ids[i] || bufObj == &DummyBufferObject);
   1482 
   1483          _mesa_buffer_unmap_all_mappings(ctx, bufObj);
   1484 
   1485          /* unbind any vertex pointers bound to this buffer */
   1486          for (j = 0; j < ARRAY_SIZE(vao->BufferBinding); j++) {
   1487             unbind(ctx, vao, j, bufObj);
   1488          }
   1489 
   1490          if (ctx->Array.ArrayBufferObj == bufObj) {
   1491             bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0);
   1492          }
   1493          if (vao->IndexBufferObj == bufObj) {
   1494             bind_buffer_object(ctx, &vao->IndexBufferObj, 0);
   1495          }
   1496 
   1497          /* unbind ARB_draw_indirect binding point */
   1498          if (ctx->DrawIndirectBuffer == bufObj) {
   1499             bind_buffer_object(ctx, &ctx->DrawIndirectBuffer, 0);
   1500          }
   1501 
   1502          /* unbind ARB_indirect_parameters binding point */
   1503          if (ctx->ParameterBuffer == bufObj) {
   1504             bind_buffer_object(ctx, &ctx->ParameterBuffer, 0);
   1505          }
   1506 
   1507          /* unbind ARB_compute_shader binding point */
   1508          if (ctx->DispatchIndirectBuffer == bufObj) {
   1509             bind_buffer_object(ctx, &ctx->DispatchIndirectBuffer, 0);
   1510          }
   1511 
   1512          /* unbind ARB_copy_buffer binding points */
   1513          if (ctx->CopyReadBuffer == bufObj) {
   1514             bind_buffer_object(ctx, &ctx->CopyReadBuffer, 0);
   1515          }
   1516          if (ctx->CopyWriteBuffer == bufObj) {
   1517             bind_buffer_object(ctx, &ctx->CopyWriteBuffer, 0);
   1518          }
   1519 
   1520          /* unbind transform feedback binding points */
   1521          if (ctx->TransformFeedback.CurrentBuffer == bufObj) {
   1522             bind_buffer_object(ctx, &ctx->TransformFeedback.CurrentBuffer, 0);
   1523          }
   1524          for (j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
   1525             if (ctx->TransformFeedback.CurrentObject->Buffers[j] == bufObj) {
   1526                _mesa_bind_buffer_base_transform_feedback(ctx,
   1527                                            ctx->TransformFeedback.CurrentObject,
   1528                                            j, ctx->Shared->NullBufferObj,
   1529                                            false);
   1530             }
   1531          }
   1532 
   1533          /* unbind UBO binding points */
   1534          for (j = 0; j < ctx->Const.MaxUniformBufferBindings; j++) {
   1535             if (ctx->UniformBufferBindings[j].BufferObject == bufObj) {
   1536                bind_buffer_base_uniform_buffer(ctx, j,
   1537                                                ctx->Shared->NullBufferObj);
   1538             }
   1539          }
   1540 
   1541          if (ctx->UniformBuffer == bufObj) {
   1542             bind_buffer_object(ctx, &ctx->UniformBuffer, 0);
   1543          }
   1544 
   1545          /* unbind SSBO binding points */
   1546          for (j = 0; j < ctx->Const.MaxShaderStorageBufferBindings; j++) {
   1547             if (ctx->ShaderStorageBufferBindings[j].BufferObject == bufObj) {
   1548                bind_buffer_base_shader_storage_buffer(ctx, j,
   1549                                                     ctx->Shared->NullBufferObj);
   1550             }
   1551          }
   1552 
   1553          if (ctx->ShaderStorageBuffer == bufObj) {
   1554             bind_buffer_object(ctx, &ctx->ShaderStorageBuffer, 0);
   1555          }
   1556 
   1557          /* unbind Atomci Buffer binding points */
   1558          for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) {
   1559             if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) {
   1560                bind_buffer_base_atomic_buffer(ctx, j,
   1561                                               ctx->Shared->NullBufferObj);
   1562             }
   1563          }
   1564 
   1565          if (ctx->AtomicBuffer == bufObj) {
   1566             bind_buffer_object(ctx, &ctx->AtomicBuffer, 0);
   1567          }
   1568 
   1569          /* unbind any pixel pack/unpack pointers bound to this buffer */
   1570          if (ctx->Pack.BufferObj == bufObj) {
   1571             bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0);
   1572          }
   1573          if (ctx->Unpack.BufferObj == bufObj) {
   1574             bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0);
   1575          }
   1576 
   1577          if (ctx->Texture.BufferObject == bufObj) {
   1578             bind_buffer_object(ctx, &ctx->Texture.BufferObject, 0);
   1579          }
   1580 
   1581          if (ctx->ExternalVirtualMemoryBuffer == bufObj) {
   1582             bind_buffer_object(ctx, &ctx->ExternalVirtualMemoryBuffer, 0);
   1583          }
   1584 
   1585          /* unbind query buffer binding point */
   1586          if (ctx->QueryBuffer == bufObj) {
   1587             bind_buffer_object(ctx, &ctx->QueryBuffer, 0);
   1588          }
   1589 
   1590          /* The ID is immediately freed for re-use */
   1591          _mesa_HashRemoveLocked(ctx->Shared->BufferObjects, ids[i]);
   1592          /* Make sure we do not run into the classic ABA problem on bind.
   1593           * We don't want to allow re-binding a buffer object that's been
   1594           * "deleted" by glDeleteBuffers().
   1595           *
   1596           * The explicit rebinding to the default object in the current context
   1597           * prevents the above in the current context, but another context
   1598           * sharing the same objects might suffer from this problem.
   1599           * The alternative would be to do the hash lookup in any case on bind
   1600           * which would introduce more runtime overhead than this.
   1601           */
   1602          bufObj->DeletePending = GL_TRUE;
   1603          _mesa_reference_buffer_object(ctx, &bufObj, NULL);
   1604       }
   1605    }
   1606 
   1607    _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   1608 }
   1609 
   1610 
   1611 void GLAPIENTRY
   1612 _mesa_DeleteBuffers_no_error(GLsizei n, const GLuint *ids)
   1613 {
   1614    GET_CURRENT_CONTEXT(ctx);
   1615    delete_buffers(ctx, n, ids);
   1616 }
   1617 
   1618 
   1619 void GLAPIENTRY
   1620 _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
   1621 {
   1622    GET_CURRENT_CONTEXT(ctx);
   1623 
   1624    if (n < 0) {
   1625       _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteBuffersARB(n)");
   1626       return;
   1627    }
   1628 
   1629    delete_buffers(ctx, n, ids);
   1630 }
   1631 
   1632 
   1633 /**
   1634  * This is the implementation for glGenBuffers and glCreateBuffers. It is not
   1635  * exposed to the rest of Mesa to encourage the use of nameless buffers in
   1636  * driver internals.
   1637  */
   1638 static void
   1639 create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
   1640 {
   1641    GLuint first;
   1642    struct gl_buffer_object *buf;
   1643 
   1644    if (!buffers)
   1645       return;
   1646 
   1647    /*
   1648     * This must be atomic (generation and allocation of buffer object IDs)
   1649     */
   1650    _mesa_HashLockMutex(ctx->Shared->BufferObjects);
   1651 
   1652    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n);
   1653 
   1654    /* Insert the ID and pointer into the hash table. If non-DSA, insert a
   1655     * DummyBufferObject.  Otherwise, create a new buffer object and insert
   1656     * it.
   1657     */
   1658    for (int i = 0; i < n; i++) {
   1659       buffers[i] = first + i;
   1660       if (dsa) {
   1661          assert(ctx->Driver.NewBufferObject);
   1662          buf = ctx->Driver.NewBufferObject(ctx, buffers[i]);
   1663          if (!buf) {
   1664             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCreateBuffers");
   1665             _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   1666             return;
   1667          }
   1668       }
   1669       else
   1670          buf = &DummyBufferObject;
   1671 
   1672       _mesa_HashInsertLocked(ctx->Shared->BufferObjects, buffers[i], buf);
   1673    }
   1674 
   1675    _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   1676 }
   1677 
   1678 
   1679 static void
   1680 create_buffers_err(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
   1681 {
   1682    const char *func = dsa ? "glCreateBuffers" : "glGenBuffers";
   1683 
   1684    if (MESA_VERBOSE & VERBOSE_API)
   1685       _mesa_debug(ctx, "%s(%d)\n", func, n);
   1686 
   1687    if (n < 0) {
   1688       _mesa_error(ctx, GL_INVALID_VALUE, "%s(n %d < 0)", func, n);
   1689       return;
   1690    }
   1691 
   1692    create_buffers(ctx, n, buffers, dsa);
   1693 }
   1694 
   1695 /**
   1696  * Generate a set of unique buffer object IDs and store them in \c buffers.
   1697  *
   1698  * \param n        Number of IDs to generate.
   1699  * \param buffers  Array of \c n locations to store the IDs.
   1700  */
   1701 void GLAPIENTRY
   1702 _mesa_GenBuffers_no_error(GLsizei n, GLuint *buffers)
   1703 {
   1704    GET_CURRENT_CONTEXT(ctx);
   1705    create_buffers(ctx, n, buffers, false);
   1706 }
   1707 
   1708 
   1709 void GLAPIENTRY
   1710 _mesa_GenBuffers(GLsizei n, GLuint *buffers)
   1711 {
   1712    GET_CURRENT_CONTEXT(ctx);
   1713    create_buffers_err(ctx, n, buffers, false);
   1714 }
   1715 
   1716 /**
   1717  * Create a set of buffer objects and store their unique IDs in \c buffers.
   1718  *
   1719  * \param n        Number of IDs to generate.
   1720  * \param buffers  Array of \c n locations to store the IDs.
   1721  */
   1722 void GLAPIENTRY
   1723 _mesa_CreateBuffers_no_error(GLsizei n, GLuint *buffers)
   1724 {
   1725    GET_CURRENT_CONTEXT(ctx);
   1726    create_buffers(ctx, n, buffers, true);
   1727 }
   1728 
   1729 
   1730 void GLAPIENTRY
   1731 _mesa_CreateBuffers(GLsizei n, GLuint *buffers)
   1732 {
   1733    GET_CURRENT_CONTEXT(ctx);
   1734    create_buffers_err(ctx, n, buffers, true);
   1735 }
   1736 
   1737 
   1738 /**
   1739  * Determine if ID is the name of a buffer object.
   1740  *
   1741  * \param id  ID of the potential buffer object.
   1742  * \return  \c GL_TRUE if \c id is the name of a buffer object,
   1743  *          \c GL_FALSE otherwise.
   1744  */
   1745 GLboolean GLAPIENTRY
   1746 _mesa_IsBuffer(GLuint id)
   1747 {
   1748    struct gl_buffer_object *bufObj;
   1749    GET_CURRENT_CONTEXT(ctx);
   1750    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
   1751 
   1752    bufObj = _mesa_lookup_bufferobj(ctx, id);
   1753 
   1754    return bufObj && bufObj != &DummyBufferObject;
   1755 }
   1756 
   1757 
   1758 static bool
   1759 validate_buffer_storage(struct gl_context *ctx,
   1760                         struct gl_buffer_object *bufObj, GLsizeiptr size,
   1761                         GLbitfield flags, const char *func)
   1762 {
   1763    if (size <= 0) {
   1764       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size <= 0)", func);
   1765       return false;
   1766    }
   1767 
   1768    GLbitfield valid_flags = GL_MAP_READ_BIT |
   1769                             GL_MAP_WRITE_BIT |
   1770                             GL_MAP_PERSISTENT_BIT |
   1771                             GL_MAP_COHERENT_BIT |
   1772                             GL_DYNAMIC_STORAGE_BIT |
   1773                             GL_CLIENT_STORAGE_BIT;
   1774 
   1775    if (ctx->Extensions.ARB_sparse_buffer)
   1776       valid_flags |= GL_SPARSE_STORAGE_BIT_ARB;
   1777 
   1778    if (flags & ~valid_flags) {
   1779       _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid flag bits set)", func);
   1780       return false;
   1781    }
   1782 
   1783    /* The Errors section of the GL_ARB_sparse_buffer spec says:
   1784     *
   1785     *    "INVALID_VALUE is generated by BufferStorage if <flags> contains
   1786     *     SPARSE_STORAGE_BIT_ARB and <flags> also contains any combination of
   1787     *     MAP_READ_BIT or MAP_WRITE_BIT."
   1788     */
   1789    if (flags & GL_SPARSE_STORAGE_BIT_ARB &&
   1790        flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
   1791       _mesa_error(ctx, GL_INVALID_VALUE, "%s(SPARSE_STORAGE and READ/WRITE)", func);
   1792       return false;
   1793    }
   1794 
   1795    if (flags & GL_MAP_PERSISTENT_BIT &&
   1796        !(flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))) {
   1797       _mesa_error(ctx, GL_INVALID_VALUE,
   1798                   "%s(PERSISTENT and flags!=READ/WRITE)", func);
   1799       return false;
   1800    }
   1801 
   1802    if (flags & GL_MAP_COHERENT_BIT && !(flags & GL_MAP_PERSISTENT_BIT)) {
   1803       _mesa_error(ctx, GL_INVALID_VALUE,
   1804                   "%s(COHERENT and flags!=PERSISTENT)", func);
   1805       return false;
   1806    }
   1807 
   1808    if (bufObj->Immutable || bufObj->HandleAllocated) {
   1809       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
   1810       return false;
   1811    }
   1812 
   1813    return true;
   1814 }
   1815 
   1816 
   1817 static void
   1818 buffer_storage(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   1819                struct gl_memory_object *memObj, GLenum target,
   1820                GLsizeiptr size, const GLvoid *data, GLbitfield flags,
   1821                GLuint64 offset, const char *func)
   1822 {
   1823    GLboolean res;
   1824 
   1825    /* Unmap the existing buffer.  We'll replace it now.  Not an error. */
   1826    _mesa_buffer_unmap_all_mappings(ctx, bufObj);
   1827 
   1828    FLUSH_VERTICES(ctx, 0);
   1829 
   1830    bufObj->Written = GL_TRUE;
   1831    bufObj->Immutable = GL_TRUE;
   1832    bufObj->MinMaxCacheDirty = true;
   1833 
   1834    if (memObj) {
   1835       assert(ctx->Driver.BufferDataMem);
   1836       res = ctx->Driver.BufferDataMem(ctx, target, size, memObj, offset,
   1837                                       GL_DYNAMIC_DRAW, bufObj);
   1838    }
   1839    else {
   1840       assert(ctx->Driver.BufferData);
   1841       res = ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW,
   1842                                    flags, bufObj);
   1843    }
   1844 
   1845    if (!res) {
   1846       if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
   1847          /* Even though the interaction between AMD_pinned_memory and
   1848           * glBufferStorage is not described in the spec, Graham Sellers
   1849           * said that it should behave the same as glBufferData.
   1850           */
   1851          _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
   1852       }
   1853       else {
   1854          _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
   1855       }
   1856    }
   1857 }
   1858 
   1859 
   1860 static ALWAYS_INLINE void
   1861 inlined_buffer_storage(GLenum target, GLuint buffer, GLsizeiptr size,
   1862                        const GLvoid *data, GLbitfield flags,
   1863                        GLuint memory, GLuint64 offset,
   1864                        bool dsa, bool mem, bool no_error, const char *func)
   1865 {
   1866    GET_CURRENT_CONTEXT(ctx);
   1867    struct gl_buffer_object *bufObj;
   1868    struct gl_memory_object *memObj = NULL;
   1869 
   1870    if (mem) {
   1871       if (!no_error) {
   1872          if (!ctx->Extensions.EXT_memory_object) {
   1873             _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
   1874             return;
   1875          }
   1876 
   1877          /* From the EXT_external_objects spec:
   1878           *
   1879           *   "An INVALID_VALUE error is generated by BufferStorageMemEXT and
   1880           *   NamedBufferStorageMemEXT if <memory> is 0, or ..."
   1881           */
   1882          if (memory == 0) {
   1883             _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory == 0)", func);
   1884          }
   1885       }
   1886 
   1887       memObj = _mesa_lookup_memory_object(ctx, memory);
   1888       if (!memObj)
   1889          return;
   1890 
   1891       /* From the EXT_external_objects spec:
   1892        *
   1893        *   "An INVALID_OPERATION error is generated if <memory> names a
   1894        *   valid memory object which has no associated memory."
   1895        */
   1896       if (!no_error && !memObj->Immutable) {
   1897          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
   1898                      func);
   1899          return;
   1900       }
   1901    }
   1902 
   1903    if (dsa) {
   1904       if (no_error) {
   1905          bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   1906       } else {
   1907          bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func);
   1908          if (!bufObj)
   1909             return;
   1910       }
   1911    } else {
   1912       if (no_error) {
   1913          struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target);
   1914          bufObj = *bufObjPtr;
   1915       } else {
   1916          bufObj = get_buffer(ctx, func, target, GL_INVALID_OPERATION);
   1917          if (!bufObj)
   1918             return;
   1919       }
   1920    }
   1921 
   1922    if (no_error || validate_buffer_storage(ctx, bufObj, size, flags, func))
   1923       buffer_storage(ctx, bufObj, memObj, target, size, data, flags, offset, func);
   1924 }
   1925 
   1926 
   1927 void GLAPIENTRY
   1928 _mesa_BufferStorage_no_error(GLenum target, GLsizeiptr size,
   1929                              const GLvoid *data, GLbitfield flags)
   1930 {
   1931    inlined_buffer_storage(target, 0, size, data, flags, GL_NONE, 0,
   1932                           false, false, true, "glBufferStorage");
   1933 }
   1934 
   1935 
   1936 void GLAPIENTRY
   1937 _mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
   1938                     GLbitfield flags)
   1939 {
   1940    inlined_buffer_storage(target, 0, size, data, flags, GL_NONE, 0,
   1941                           false, false, false, "glBufferStorage");
   1942 }
   1943 
   1944 
   1945 void GLAPIENTRY
   1946 _mesa_BufferStorageMemEXT(GLenum target, GLsizeiptr size,
   1947                           GLuint memory, GLuint64 offset)
   1948 {
   1949    inlined_buffer_storage(target, 0, size, NULL, 0, memory, offset,
   1950                           false, true, false, "glBufferStorageMemEXT");
   1951 }
   1952 
   1953 
   1954 void GLAPIENTRY
   1955 _mesa_BufferStorageMemEXT_no_error(GLenum target, GLsizeiptr size,
   1956                                    GLuint memory, GLuint64 offset)
   1957 {
   1958    inlined_buffer_storage(target, 0, size, NULL, 0, memory, offset,
   1959                           false, true, true, "glBufferStorageMemEXT");
   1960 }
   1961 
   1962 
   1963 void GLAPIENTRY
   1964 _mesa_NamedBufferStorage_no_error(GLuint buffer, GLsizeiptr size,
   1965                                   const GLvoid *data, GLbitfield flags)
   1966 {
   1967    /* In direct state access, buffer objects have an unspecified target
   1968     * since they are not required to be bound.
   1969     */
   1970    inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0,
   1971                           true, false, true, "glNamedBufferStorage");
   1972 }
   1973 
   1974 
   1975 void GLAPIENTRY
   1976 _mesa_NamedBufferStorage(GLuint buffer, GLsizeiptr size, const GLvoid *data,
   1977                          GLbitfield flags)
   1978 {
   1979    /* In direct state access, buffer objects have an unspecified target
   1980     * since they are not required to be bound.
   1981     */
   1982    inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0,
   1983                           true, false, false, "glNamedBufferStorage");
   1984 }
   1985 
   1986 void GLAPIENTRY
   1987 _mesa_NamedBufferStorageMemEXT(GLuint buffer, GLsizeiptr size,
   1988                                GLuint memory, GLuint64 offset)
   1989 {
   1990    inlined_buffer_storage(GL_NONE, buffer, size, GL_NONE, 0, memory, offset,
   1991                           true, true, false, "glNamedBufferStorageMemEXT");
   1992 }
   1993 
   1994 
   1995 void GLAPIENTRY
   1996 _mesa_NamedBufferStorageMemEXT_no_error(GLuint buffer, GLsizeiptr size,
   1997                                         GLuint memory, GLuint64 offset)
   1998 {
   1999    inlined_buffer_storage(GL_NONE, buffer, size, GL_NONE, 0, memory, offset,
   2000                           true, true, true, "glNamedBufferStorageMemEXT");
   2001 }
   2002 
   2003 
   2004 static ALWAYS_INLINE void
   2005 buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   2006             GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage,
   2007             const char *func, bool no_error)
   2008 {
   2009    bool valid_usage;
   2010 
   2011    if (MESA_VERBOSE & VERBOSE_API) {
   2012       _mesa_debug(ctx, "%s(%s, %ld, %p, %s)\n",
   2013                   func,
   2014                   _mesa_enum_to_string(target),
   2015                   (long int) size, data,
   2016                   _mesa_enum_to_string(usage));
   2017    }
   2018 
   2019    if (!no_error) {
   2020       if (size < 0) {
   2021          _mesa_error(ctx, GL_INVALID_VALUE, "%s(size < 0)", func);
   2022          return;
   2023       }
   2024 
   2025       switch (usage) {
   2026       case GL_STREAM_DRAW_ARB:
   2027          valid_usage = (ctx->API != API_OPENGLES);
   2028          break;
   2029       case GL_STATIC_DRAW_ARB:
   2030       case GL_DYNAMIC_DRAW_ARB:
   2031          valid_usage = true;
   2032          break;
   2033       case GL_STREAM_READ_ARB:
   2034       case GL_STREAM_COPY_ARB:
   2035       case GL_STATIC_READ_ARB:
   2036       case GL_STATIC_COPY_ARB:
   2037       case GL_DYNAMIC_READ_ARB:
   2038       case GL_DYNAMIC_COPY_ARB:
   2039          valid_usage = _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx);
   2040          break;
   2041       default:
   2042          valid_usage = false;
   2043          break;
   2044       }
   2045 
   2046       if (!valid_usage) {
   2047          _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid usage: %s)", func,
   2048                      _mesa_enum_to_string(usage));
   2049          return;
   2050       }
   2051 
   2052       if (bufObj->Immutable || bufObj->HandleAllocated) {
   2053          _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
   2054          return;
   2055       }
   2056    }
   2057 
   2058    /* Unmap the existing buffer.  We'll replace it now.  Not an error. */
   2059    _mesa_buffer_unmap_all_mappings(ctx, bufObj);
   2060 
   2061    FLUSH_VERTICES(ctx, 0);
   2062 
   2063    bufObj->Written = GL_TRUE;
   2064    bufObj->MinMaxCacheDirty = true;
   2065 
   2066 #ifdef VBO_DEBUG
   2067    printf("glBufferDataARB(%u, sz %ld, from %p, usage 0x%x)\n",
   2068                 bufObj->Name, size, data, usage);
   2069 #endif
   2070 
   2071 #ifdef BOUNDS_CHECK
   2072    size += 100;
   2073 #endif
   2074 
   2075    assert(ctx->Driver.BufferData);
   2076    if (!ctx->Driver.BufferData(ctx, target, size, data, usage,
   2077                                GL_MAP_READ_BIT |
   2078                                GL_MAP_WRITE_BIT |
   2079                                GL_DYNAMIC_STORAGE_BIT,
   2080                                bufObj)) {
   2081       if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
   2082          if (!no_error) {
   2083             /* From GL_AMD_pinned_memory:
   2084              *
   2085              *   INVALID_OPERATION is generated by BufferData if <target> is
   2086              *   EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, and the store cannot be
   2087              *   mapped to the GPU address space.
   2088              */
   2089             _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
   2090          }
   2091       } else {
   2092          _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
   2093       }
   2094    }
   2095 }
   2096 
   2097 static void
   2098 buffer_data_error(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   2099                   GLenum target, GLsizeiptr size, const GLvoid *data,
   2100                   GLenum usage, const char *func)
   2101 {
   2102    buffer_data(ctx, bufObj, target, size, data, usage, func, false);
   2103 }
   2104 
   2105 static void
   2106 buffer_data_no_error(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   2107                      GLenum target, GLsizeiptr size, const GLvoid *data,
   2108                      GLenum usage, const char *func)
   2109 {
   2110    buffer_data(ctx, bufObj, target, size, data, usage, func, true);
   2111 }
   2112 
   2113 void
   2114 _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   2115                   GLenum target, GLsizeiptr size, const GLvoid *data,
   2116                   GLenum usage, const char *func)
   2117 {
   2118    buffer_data_error(ctx, bufObj, target, size, data, usage, func);
   2119 }
   2120 
   2121 void GLAPIENTRY
   2122 _mesa_BufferData_no_error(GLenum target, GLsizeiptr size, const GLvoid *data,
   2123                           GLenum usage)
   2124 {
   2125    GET_CURRENT_CONTEXT(ctx);
   2126 
   2127    struct gl_buffer_object **bufObj = get_buffer_target(ctx, target);
   2128    buffer_data_no_error(ctx, *bufObj, target, size, data, usage,
   2129                         "glBufferData");
   2130 }
   2131 
   2132 void GLAPIENTRY
   2133 _mesa_BufferData(GLenum target, GLsizeiptr size,
   2134                  const GLvoid *data, GLenum usage)
   2135 {
   2136    GET_CURRENT_CONTEXT(ctx);
   2137    struct gl_buffer_object *bufObj;
   2138 
   2139    bufObj = get_buffer(ctx, "glBufferData", target, GL_INVALID_OPERATION);
   2140    if (!bufObj)
   2141       return;
   2142 
   2143    _mesa_buffer_data(ctx, bufObj, target, size, data, usage,
   2144                      "glBufferData");
   2145 }
   2146 
   2147 void GLAPIENTRY
   2148 _mesa_NamedBufferData_no_error(GLuint buffer, GLsizeiptr size,
   2149                                const GLvoid *data, GLenum usage)
   2150 {
   2151    GET_CURRENT_CONTEXT(ctx);
   2152 
   2153    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   2154    buffer_data_no_error(ctx, bufObj, GL_NONE, size, data, usage,
   2155                         "glNamedBufferData");
   2156 }
   2157 
   2158 void GLAPIENTRY
   2159 _mesa_NamedBufferData(GLuint buffer, GLsizeiptr size, const GLvoid *data,
   2160                       GLenum usage)
   2161 {
   2162    GET_CURRENT_CONTEXT(ctx);
   2163    struct gl_buffer_object *bufObj;
   2164 
   2165    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glNamedBufferData");
   2166    if (!bufObj)
   2167       return;
   2168 
   2169    /* In direct state access, buffer objects have an unspecified target since
   2170     * they are not required to be bound.
   2171     */
   2172    _mesa_buffer_data(ctx, bufObj, GL_NONE, size, data, usage,
   2173                      "glNamedBufferData");
   2174 }
   2175 
   2176 
   2177 static bool
   2178 validate_buffer_sub_data(struct gl_context *ctx,
   2179                          struct gl_buffer_object *bufObj,
   2180                          GLintptr offset, GLsizeiptr size,
   2181                          const char *func)
   2182 {
   2183    if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size,
   2184                                          true, func)) {
   2185       /* error already recorded */
   2186       return false;
   2187    }
   2188 
   2189    if (bufObj->Immutable &&
   2190        !(bufObj->StorageFlags & GL_DYNAMIC_STORAGE_BIT)) {
   2191       _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
   2192       return false;
   2193    }
   2194 
   2195    if ((bufObj->Usage == GL_STATIC_DRAW ||
   2196         bufObj->Usage == GL_STATIC_COPY) &&
   2197        bufObj->NumSubDataCalls >= BUFFER_WARNING_CALL_COUNT - 1) {
   2198       /* If the application declared the buffer as static draw/copy or stream
   2199        * draw, it should not be frequently modified with glBufferSubData.
   2200        */
   2201       BUFFER_USAGE_WARNING(ctx,
   2202                            "using %s(buffer %u, offset %u, size %u) to "
   2203                            "update a %s buffer",
   2204                            func, bufObj->Name, offset, size,
   2205                            _mesa_enum_to_string(bufObj->Usage));
   2206    }
   2207 
   2208    return true;
   2209 }
   2210 
   2211 
   2212 /**
   2213  * Implementation for glBufferSubData and glNamedBufferSubData.
   2214  *
   2215  * \param ctx     GL context.
   2216  * \param bufObj  The buffer object.
   2217  * \param offset  Offset of the first byte of the subdata range.
   2218  * \param size    Size, in bytes, of the subdata range.
   2219  * \param data    The data store.
   2220  * \param func  Name of calling function for recording errors.
   2221  *
   2222  */
   2223 void
   2224 _mesa_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   2225                       GLintptr offset, GLsizeiptr size, const GLvoid *data)
   2226 {
   2227    if (size == 0)
   2228       return;
   2229 
   2230    bufObj->NumSubDataCalls++;
   2231    bufObj->Written = GL_TRUE;
   2232    bufObj->MinMaxCacheDirty = true;
   2233 
   2234    assert(ctx->Driver.BufferSubData);
   2235    ctx->Driver.BufferSubData(ctx, offset, size, data, bufObj);
   2236 }
   2237 
   2238 
   2239 static ALWAYS_INLINE void
   2240 buffer_sub_data(GLenum target, GLuint buffer, GLintptr offset,
   2241                 GLsizeiptr size, const GLvoid *data,
   2242                 bool dsa, bool no_error, const char *func)
   2243 {
   2244    GET_CURRENT_CONTEXT(ctx);
   2245    struct gl_buffer_object *bufObj;
   2246 
   2247    if (dsa) {
   2248       if (no_error) {
   2249          bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   2250       } else {
   2251          bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func);
   2252          if (!bufObj)
   2253             return;
   2254       }
   2255    } else {
   2256       if (no_error) {
   2257          struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target);
   2258          bufObj = *bufObjPtr;
   2259       } else {
   2260          bufObj = get_buffer(ctx, func, target, GL_INVALID_OPERATION);
   2261          if (!bufObj)
   2262             return;
   2263       }
   2264    }
   2265 
   2266    if (no_error || validate_buffer_sub_data(ctx, bufObj, offset, size, func))
   2267       _mesa_buffer_sub_data(ctx, bufObj, offset, size, data);
   2268 }
   2269 
   2270 
   2271 void GLAPIENTRY
   2272 _mesa_BufferSubData_no_error(GLenum target, GLintptr offset,
   2273                              GLsizeiptr size, const GLvoid *data)
   2274 {
   2275    buffer_sub_data(target, 0, offset, size, data, false, true,
   2276                    "glBufferSubData");
   2277 }
   2278 
   2279 
   2280 void GLAPIENTRY
   2281 _mesa_BufferSubData(GLenum target, GLintptr offset,
   2282                     GLsizeiptr size, const GLvoid *data)
   2283 {
   2284    buffer_sub_data(target, 0, offset, size, data, false, false,
   2285                    "glBufferSubData");
   2286 }
   2287 
   2288 void GLAPIENTRY
   2289 _mesa_NamedBufferSubData_no_error(GLuint buffer, GLintptr offset,
   2290                                   GLsizeiptr size, const GLvoid *data)
   2291 {
   2292    buffer_sub_data(0, buffer, offset, size, data, true, true,
   2293                    "glNamedBufferSubData");
   2294 }
   2295 
   2296 void GLAPIENTRY
   2297 _mesa_NamedBufferSubData(GLuint buffer, GLintptr offset,
   2298                          GLsizeiptr size, const GLvoid *data)
   2299 {
   2300    buffer_sub_data(0, buffer, offset, size, data, true, false,
   2301                    "glNamedBufferSubData");
   2302 }
   2303 
   2304 
   2305 void GLAPIENTRY
   2306 _mesa_GetBufferSubData(GLenum target, GLintptr offset,
   2307                        GLsizeiptr size, GLvoid *data)
   2308 {
   2309    GET_CURRENT_CONTEXT(ctx);
   2310    struct gl_buffer_object *bufObj;
   2311 
   2312    bufObj = get_buffer(ctx, "glGetBufferSubData", target,
   2313                        GL_INVALID_OPERATION);
   2314    if (!bufObj)
   2315       return;
   2316 
   2317    if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false,
   2318                                          "glGetBufferSubData")) {
   2319       return;
   2320    }
   2321 
   2322    assert(ctx->Driver.GetBufferSubData);
   2323    ctx->Driver.GetBufferSubData(ctx, offset, size, data, bufObj);
   2324 }
   2325 
   2326 void GLAPIENTRY
   2327 _mesa_GetNamedBufferSubData(GLuint buffer, GLintptr offset,
   2328                             GLsizeiptr size, GLvoid *data)
   2329 {
   2330    GET_CURRENT_CONTEXT(ctx);
   2331    struct gl_buffer_object *bufObj;
   2332 
   2333    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
   2334                                        "glGetNamedBufferSubData");
   2335    if (!bufObj)
   2336       return;
   2337 
   2338    if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false,
   2339                                          "glGetNamedBufferSubData")) {
   2340       return;
   2341    }
   2342 
   2343    assert(ctx->Driver.GetBufferSubData);
   2344    ctx->Driver.GetBufferSubData(ctx, offset, size, data, bufObj);
   2345 }
   2346 
   2347 
   2348 /**
   2349  * \param subdata   true if caller is *SubData, false if *Data
   2350  */
   2351 static ALWAYS_INLINE void
   2352 clear_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   2353                       GLenum internalformat, GLintptr offset, GLsizeiptr size,
   2354                       GLenum format, GLenum type, const GLvoid *data,
   2355                       const char *func, bool subdata, bool no_error)
   2356 {
   2357    mesa_format mesaFormat;
   2358    GLubyte clearValue[MAX_PIXEL_BYTES];
   2359    GLsizeiptr clearValueSize;
   2360 
   2361    /* This checks for disallowed mappings. */
   2362    if (!no_error && !buffer_object_subdata_range_good(ctx, bufObj, offset, size,
   2363                                                       subdata, func)) {
   2364       return;
   2365    }
   2366 
   2367    if (no_error) {
   2368       mesaFormat = _mesa_get_texbuffer_format(ctx, internalformat);
   2369    } else {
   2370       mesaFormat = validate_clear_buffer_format(ctx, internalformat,
   2371                                                 format, type, func);
   2372    }
   2373 
   2374    if (mesaFormat == MESA_FORMAT_NONE)
   2375       return;
   2376 
   2377    clearValueSize = _mesa_get_format_bytes(mesaFormat);
   2378    if (!no_error &&
   2379        (offset % clearValueSize != 0 || size % clearValueSize != 0)) {
   2380       _mesa_error(ctx, GL_INVALID_VALUE,
   2381                   "%s(offset or size is not a multiple of "
   2382                   "internalformat size)", func);
   2383       return;
   2384    }
   2385 
   2386    /* Bail early. Negative size has already been checked. */
   2387    if (size == 0)
   2388       return;
   2389 
   2390    bufObj->MinMaxCacheDirty = true;
   2391 
   2392    if (data == NULL) {
   2393       /* clear to zeros, per the spec */
   2394       ctx->Driver.ClearBufferSubData(ctx, offset, size,
   2395                                      NULL, clearValueSize, bufObj);
   2396       return;
   2397    }
   2398 
   2399    if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue,
   2400                                   format, type, data, func)) {
   2401       return;
   2402    }
   2403 
   2404    ctx->Driver.ClearBufferSubData(ctx, offset, size,
   2405                                   clearValue, clearValueSize, bufObj);
   2406 }
   2407 
   2408 static void
   2409 clear_buffer_sub_data_error(struct gl_context *ctx,
   2410                             struct gl_buffer_object *bufObj,
   2411                             GLenum internalformat, GLintptr offset,
   2412                             GLsizeiptr size, GLenum format, GLenum type,
   2413                             const GLvoid *data, const char *func, bool subdata)
   2414 {
   2415    clear_buffer_sub_data(ctx, bufObj, internalformat, offset, size, format,
   2416                          type, data, func, subdata, false);
   2417 }
   2418 
   2419 
   2420 static void
   2421 clear_buffer_sub_data_no_error(struct gl_context *ctx,
   2422                                struct gl_buffer_object *bufObj,
   2423                                GLenum internalformat, GLintptr offset,
   2424                                GLsizeiptr size, GLenum format, GLenum type,
   2425                                const GLvoid *data, const char *func,
   2426                                bool subdata)
   2427 {
   2428    clear_buffer_sub_data(ctx, bufObj, internalformat, offset, size, format,
   2429                          type, data, func, subdata, true);
   2430 }
   2431 
   2432 
   2433 void GLAPIENTRY
   2434 _mesa_ClearBufferData_no_error(GLenum target, GLenum internalformat,
   2435                                GLenum format, GLenum type, const GLvoid *data)
   2436 {
   2437    GET_CURRENT_CONTEXT(ctx);
   2438 
   2439    struct gl_buffer_object **bufObj = get_buffer_target(ctx, target);
   2440    clear_buffer_sub_data_no_error(ctx, *bufObj, internalformat, 0,
   2441                                   (*bufObj)->Size, format, type, data,
   2442                                   "glClearBufferData", false);
   2443 }
   2444 
   2445 
   2446 void GLAPIENTRY
   2447 _mesa_ClearBufferData(GLenum target, GLenum internalformat, GLenum format,
   2448                       GLenum type, const GLvoid *data)
   2449 {
   2450    GET_CURRENT_CONTEXT(ctx);
   2451    struct gl_buffer_object *bufObj;
   2452 
   2453    bufObj = get_buffer(ctx, "glClearBufferData", target, GL_INVALID_VALUE);
   2454    if (!bufObj)
   2455       return;
   2456 
   2457    clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size,
   2458                                format, type, data, "glClearBufferData", false);
   2459 }
   2460 
   2461 
   2462 void GLAPIENTRY
   2463 _mesa_ClearNamedBufferData_no_error(GLuint buffer, GLenum internalformat,
   2464                                     GLenum format, GLenum type,
   2465                                     const GLvoid *data)
   2466 {
   2467    GET_CURRENT_CONTEXT(ctx);
   2468 
   2469    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   2470    clear_buffer_sub_data_no_error(ctx, bufObj, internalformat, 0, bufObj->Size,
   2471                                   format, type, data, "glClearNamedBufferData",
   2472                                   false);
   2473 }
   2474 
   2475 
   2476 void GLAPIENTRY
   2477 _mesa_ClearNamedBufferData(GLuint buffer, GLenum internalformat,
   2478                            GLenum format, GLenum type, const GLvoid *data)
   2479 {
   2480    GET_CURRENT_CONTEXT(ctx);
   2481    struct gl_buffer_object *bufObj;
   2482 
   2483    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glClearNamedBufferData");
   2484    if (!bufObj)
   2485       return;
   2486 
   2487    clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size,
   2488                                format, type, data, "glClearNamedBufferData",
   2489                                false);
   2490 }
   2491 
   2492 
   2493 void GLAPIENTRY
   2494 _mesa_ClearBufferSubData_no_error(GLenum target, GLenum internalformat,
   2495                                   GLintptr offset, GLsizeiptr size,
   2496                                   GLenum format, GLenum type,
   2497                                   const GLvoid *data)
   2498 {
   2499    GET_CURRENT_CONTEXT(ctx);
   2500 
   2501    struct gl_buffer_object **bufObj = get_buffer_target(ctx, target);
   2502    clear_buffer_sub_data_no_error(ctx, *bufObj, internalformat, offset, size,
   2503                                   format, type, data, "glClearBufferSubData",
   2504                                   true);
   2505 }
   2506 
   2507 
   2508 void GLAPIENTRY
   2509 _mesa_ClearBufferSubData(GLenum target, GLenum internalformat,
   2510                          GLintptr offset, GLsizeiptr size,
   2511                          GLenum format, GLenum type,
   2512                          const GLvoid *data)
   2513 {
   2514    GET_CURRENT_CONTEXT(ctx);
   2515    struct gl_buffer_object *bufObj;
   2516 
   2517    bufObj = get_buffer(ctx, "glClearBufferSubData", target, GL_INVALID_VALUE);
   2518    if (!bufObj)
   2519       return;
   2520 
   2521    clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size,
   2522                                format, type, data, "glClearBufferSubData",
   2523                                true);
   2524 }
   2525 
   2526 
   2527 void GLAPIENTRY
   2528 _mesa_ClearNamedBufferSubData_no_error(GLuint buffer, GLenum internalformat,
   2529                                        GLintptr offset, GLsizeiptr size,
   2530                                        GLenum format, GLenum type,
   2531                                        const GLvoid *data)
   2532 {
   2533    GET_CURRENT_CONTEXT(ctx);
   2534 
   2535    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   2536    clear_buffer_sub_data_no_error(ctx, bufObj, internalformat, offset, size,
   2537                                   format, type, data,
   2538                                   "glClearNamedBufferSubData", true);
   2539 }
   2540 
   2541 
   2542 void GLAPIENTRY
   2543 _mesa_ClearNamedBufferSubData(GLuint buffer, GLenum internalformat,
   2544                               GLintptr offset, GLsizeiptr size,
   2545                               GLenum format, GLenum type,
   2546                               const GLvoid *data)
   2547 {
   2548    GET_CURRENT_CONTEXT(ctx);
   2549    struct gl_buffer_object *bufObj;
   2550 
   2551    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
   2552                                        "glClearNamedBufferSubData");
   2553    if (!bufObj)
   2554       return;
   2555 
   2556    clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size,
   2557                                format, type, data, "glClearNamedBufferSubData",
   2558                                true);
   2559 }
   2560 
   2561 static GLboolean
   2562 unmap_buffer(struct gl_context *ctx, struct gl_buffer_object *bufObj)
   2563 {
   2564    GLboolean status = ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_USER);
   2565    bufObj->Mappings[MAP_USER].AccessFlags = 0;
   2566    assert(bufObj->Mappings[MAP_USER].Pointer == NULL);
   2567    assert(bufObj->Mappings[MAP_USER].Offset == 0);
   2568    assert(bufObj->Mappings[MAP_USER].Length == 0);
   2569 
   2570    return status;
   2571 }
   2572 
   2573 static GLboolean
   2574 validate_and_unmap_buffer(struct gl_context *ctx,
   2575                           struct gl_buffer_object *bufObj,
   2576                           const char *func)
   2577 {
   2578    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
   2579 
   2580    if (!_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
   2581       _mesa_error(ctx, GL_INVALID_OPERATION,
   2582                   "%s(buffer is not mapped)", func);
   2583       return GL_FALSE;
   2584    }
   2585 
   2586 #ifdef BOUNDS_CHECK
   2587    if (bufObj->Access != GL_READ_ONLY_ARB) {
   2588       GLubyte *buf = (GLubyte *) bufObj->Pointer;
   2589       GLuint i;
   2590       /* check that last 100 bytes are still = magic value */
   2591       for (i = 0; i < 100; i++) {
   2592          GLuint pos = bufObj->Size - i - 1;
   2593          if (buf[pos] != 123) {
   2594             _mesa_warning(ctx, "Out of bounds buffer object write detected"
   2595                           " at position %d (value = %u)\n",
   2596                           pos, buf[pos]);
   2597          }
   2598       }
   2599    }
   2600 #endif
   2601 
   2602 #ifdef VBO_DEBUG
   2603    if (bufObj->AccessFlags & GL_MAP_WRITE_BIT) {
   2604       GLuint i, unchanged = 0;
   2605       GLubyte *b = (GLubyte *) bufObj->Pointer;
   2606       GLint pos = -1;
   2607       /* check which bytes changed */
   2608       for (i = 0; i < bufObj->Size - 1; i++) {
   2609          if (b[i] == (i & 0xff) && b[i+1] == ((i+1) & 0xff)) {
   2610             unchanged++;
   2611             if (pos == -1)
   2612                pos = i;
   2613          }
   2614       }
   2615       if (unchanged) {
   2616          printf("glUnmapBufferARB(%u): %u of %ld unchanged, starting at %d\n",
   2617                       bufObj->Name, unchanged, bufObj->Size, pos);
   2618       }
   2619    }
   2620 #endif
   2621 
   2622    return unmap_buffer(ctx, bufObj);
   2623 }
   2624 
   2625 GLboolean GLAPIENTRY
   2626 _mesa_UnmapBuffer_no_error(GLenum target)
   2627 {
   2628    GET_CURRENT_CONTEXT(ctx);
   2629    struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target);
   2630    struct gl_buffer_object *bufObj = *bufObjPtr;
   2631 
   2632    return unmap_buffer(ctx, bufObj);
   2633 }
   2634 
   2635 GLboolean GLAPIENTRY
   2636 _mesa_UnmapBuffer(GLenum target)
   2637 {
   2638    GET_CURRENT_CONTEXT(ctx);
   2639    struct gl_buffer_object *bufObj;
   2640 
   2641    bufObj = get_buffer(ctx, "glUnmapBuffer", target, GL_INVALID_OPERATION);
   2642    if (!bufObj)
   2643       return GL_FALSE;
   2644 
   2645    return validate_and_unmap_buffer(ctx, bufObj, "glUnmapBuffer");
   2646 }
   2647 
   2648 GLboolean GLAPIENTRY
   2649 _mesa_UnmapNamedBuffer_no_error(GLuint buffer)
   2650 {
   2651    GET_CURRENT_CONTEXT(ctx);
   2652    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   2653 
   2654    return unmap_buffer(ctx, bufObj);
   2655 }
   2656 
   2657 GLboolean GLAPIENTRY
   2658 _mesa_UnmapNamedBuffer(GLuint buffer)
   2659 {
   2660    GET_CURRENT_CONTEXT(ctx);
   2661    struct gl_buffer_object *bufObj;
   2662 
   2663    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glUnmapNamedBuffer");
   2664    if (!bufObj)
   2665       return GL_FALSE;
   2666 
   2667    return validate_and_unmap_buffer(ctx, bufObj, "glUnmapNamedBuffer");
   2668 }
   2669 
   2670 
   2671 static bool
   2672 get_buffer_parameter(struct gl_context *ctx,
   2673                      struct gl_buffer_object *bufObj, GLenum pname,
   2674                      GLint64 *params, const char *func)
   2675 {
   2676    switch (pname) {
   2677    case GL_BUFFER_SIZE_ARB:
   2678       *params = bufObj->Size;
   2679       break;
   2680    case GL_BUFFER_USAGE_ARB:
   2681       *params = bufObj->Usage;
   2682       break;
   2683    case GL_BUFFER_ACCESS_ARB:
   2684       *params = simplified_access_mode(ctx,
   2685                             bufObj->Mappings[MAP_USER].AccessFlags);
   2686       break;
   2687    case GL_BUFFER_MAPPED_ARB:
   2688       *params = _mesa_bufferobj_mapped(bufObj, MAP_USER);
   2689       break;
   2690    case GL_BUFFER_ACCESS_FLAGS:
   2691       if (!ctx->Extensions.ARB_map_buffer_range)
   2692          goto invalid_pname;
   2693       *params = bufObj->Mappings[MAP_USER].AccessFlags;
   2694       break;
   2695    case GL_BUFFER_MAP_OFFSET:
   2696       if (!ctx->Extensions.ARB_map_buffer_range)
   2697          goto invalid_pname;
   2698       *params = bufObj->Mappings[MAP_USER].Offset;
   2699       break;
   2700    case GL_BUFFER_MAP_LENGTH:
   2701       if (!ctx->Extensions.ARB_map_buffer_range)
   2702          goto invalid_pname;
   2703       *params = bufObj->Mappings[MAP_USER].Length;
   2704       break;
   2705    case GL_BUFFER_IMMUTABLE_STORAGE:
   2706       if (!ctx->Extensions.ARB_buffer_storage)
   2707          goto invalid_pname;
   2708       *params = bufObj->Immutable;
   2709       break;
   2710    case GL_BUFFER_STORAGE_FLAGS:
   2711       if (!ctx->Extensions.ARB_buffer_storage)
   2712          goto invalid_pname;
   2713       *params = bufObj->StorageFlags;
   2714       break;
   2715    default:
   2716       goto invalid_pname;
   2717    }
   2718 
   2719    return true;
   2720 
   2721 invalid_pname:
   2722    _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname: %s)", func,
   2723                _mesa_enum_to_string(pname));
   2724    return false;
   2725 }
   2726 
   2727 void GLAPIENTRY
   2728 _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
   2729 {
   2730    GET_CURRENT_CONTEXT(ctx);
   2731    struct gl_buffer_object *bufObj;
   2732    GLint64 parameter;
   2733 
   2734    bufObj = get_buffer(ctx, "glGetBufferParameteriv", target,
   2735                        GL_INVALID_OPERATION);
   2736    if (!bufObj)
   2737       return;
   2738 
   2739    if (!get_buffer_parameter(ctx, bufObj, pname, &parameter,
   2740                              "glGetBufferParameteriv"))
   2741       return; /* Error already recorded. */
   2742 
   2743    *params = (GLint) parameter;
   2744 }
   2745 
   2746 void GLAPIENTRY
   2747 _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
   2748 {
   2749    GET_CURRENT_CONTEXT(ctx);
   2750    struct gl_buffer_object *bufObj;
   2751    GLint64 parameter;
   2752 
   2753    bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target,
   2754                        GL_INVALID_OPERATION);
   2755    if (!bufObj)
   2756       return;
   2757 
   2758    if (!get_buffer_parameter(ctx, bufObj, pname, &parameter,
   2759                              "glGetBufferParameteri64v"))
   2760       return; /* Error already recorded. */
   2761 
   2762    *params = parameter;
   2763 }
   2764 
   2765 void GLAPIENTRY
   2766 _mesa_GetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params)
   2767 {
   2768    GET_CURRENT_CONTEXT(ctx);
   2769    struct gl_buffer_object *bufObj;
   2770    GLint64 parameter;
   2771 
   2772    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
   2773                                        "glGetNamedBufferParameteriv");
   2774    if (!bufObj)
   2775       return;
   2776 
   2777    if (!get_buffer_parameter(ctx, bufObj, pname, &parameter,
   2778                              "glGetNamedBufferParameteriv"))
   2779       return; /* Error already recorded. */
   2780 
   2781    *params = (GLint) parameter;
   2782 }
   2783 
   2784 void GLAPIENTRY
   2785 _mesa_GetNamedBufferParameteri64v(GLuint buffer, GLenum pname,
   2786                                   GLint64 *params)
   2787 {
   2788    GET_CURRENT_CONTEXT(ctx);
   2789    struct gl_buffer_object *bufObj;
   2790    GLint64 parameter;
   2791 
   2792    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
   2793                                        "glGetNamedBufferParameteri64v");
   2794    if (!bufObj)
   2795       return;
   2796 
   2797    if (!get_buffer_parameter(ctx, bufObj, pname, &parameter,
   2798                              "glGetNamedBufferParameteri64v"))
   2799       return; /* Error already recorded. */
   2800 
   2801    *params = parameter;
   2802 }
   2803 
   2804 
   2805 void GLAPIENTRY
   2806 _mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params)
   2807 {
   2808    GET_CURRENT_CONTEXT(ctx);
   2809    struct gl_buffer_object *bufObj;
   2810 
   2811    if (pname != GL_BUFFER_MAP_POINTER) {
   2812       _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointerv(pname != "
   2813                   "GL_BUFFER_MAP_POINTER)");
   2814       return;
   2815    }
   2816 
   2817    bufObj = get_buffer(ctx, "glGetBufferPointerv", target,
   2818                        GL_INVALID_OPERATION);
   2819    if (!bufObj)
   2820       return;
   2821 
   2822    *params = bufObj->Mappings[MAP_USER].Pointer;
   2823 }
   2824 
   2825 void GLAPIENTRY
   2826 _mesa_GetNamedBufferPointerv(GLuint buffer, GLenum pname, GLvoid **params)
   2827 {
   2828    GET_CURRENT_CONTEXT(ctx);
   2829    struct gl_buffer_object *bufObj;
   2830 
   2831    if (pname != GL_BUFFER_MAP_POINTER) {
   2832       _mesa_error(ctx, GL_INVALID_ENUM, "glGetNamedBufferPointerv(pname != "
   2833                   "GL_BUFFER_MAP_POINTER)");
   2834       return;
   2835    }
   2836 
   2837    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
   2838                                        "glGetNamedBufferPointerv");
   2839    if (!bufObj)
   2840       return;
   2841 
   2842    *params = bufObj->Mappings[MAP_USER].Pointer;
   2843 }
   2844 
   2845 
   2846 static void
   2847 copy_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *src,
   2848                      struct gl_buffer_object *dst, GLintptr readOffset,
   2849                      GLintptr writeOffset, GLsizeiptr size, const char *func)
   2850 {
   2851    if (_mesa_check_disallowed_mapping(src)) {
   2852       _mesa_error(ctx, GL_INVALID_OPERATION,
   2853                   "%s(readBuffer is mapped)", func);
   2854       return;
   2855    }
   2856 
   2857    if (_mesa_check_disallowed_mapping(dst)) {
   2858       _mesa_error(ctx, GL_INVALID_OPERATION,
   2859                   "%s(writeBuffer is mapped)", func);
   2860       return;
   2861    }
   2862 
   2863    if (readOffset < 0) {
   2864       _mesa_error(ctx, GL_INVALID_VALUE,
   2865                   "%s(readOffset %d < 0)", func, (int) readOffset);
   2866       return;
   2867    }
   2868 
   2869    if (writeOffset < 0) {
   2870       _mesa_error(ctx, GL_INVALID_VALUE,
   2871                   "%s(writeOffset %d < 0)", func, (int) writeOffset);
   2872       return;
   2873    }
   2874 
   2875    if (size < 0) {
   2876       _mesa_error(ctx, GL_INVALID_VALUE,
   2877                   "%s(size %d < 0)", func, (int) size);
   2878       return;
   2879    }
   2880 
   2881    if (readOffset + size > src->Size) {
   2882       _mesa_error(ctx, GL_INVALID_VALUE,
   2883                   "%s(readOffset %d + size %d > src_buffer_size %d)", func,
   2884                   (int) readOffset, (int) size, (int) src->Size);
   2885       return;
   2886    }
   2887 
   2888    if (writeOffset + size > dst->Size) {
   2889       _mesa_error(ctx, GL_INVALID_VALUE,
   2890                   "%s(writeOffset %d + size %d > dst_buffer_size %d)", func,
   2891                   (int) writeOffset, (int) size, (int) dst->Size);
   2892       return;
   2893    }
   2894 
   2895    if (src == dst) {
   2896       if (readOffset + size <= writeOffset) {
   2897          /* OK */
   2898       }
   2899       else if (writeOffset + size <= readOffset) {
   2900          /* OK */
   2901       }
   2902       else {
   2903          /* overlapping src/dst is illegal */
   2904          _mesa_error(ctx, GL_INVALID_VALUE,
   2905                      "%s(overlapping src/dst)", func);
   2906          return;
   2907       }
   2908    }
   2909 
   2910    dst->MinMaxCacheDirty = true;
   2911 
   2912    ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset, size);
   2913 }
   2914 
   2915 void GLAPIENTRY
   2916 _mesa_CopyBufferSubData_no_error(GLenum readTarget, GLenum writeTarget,
   2917                                  GLintptr readOffset, GLintptr writeOffset,
   2918                                  GLsizeiptr size)
   2919 {
   2920    GET_CURRENT_CONTEXT(ctx);
   2921 
   2922    struct gl_buffer_object **src_ptr = get_buffer_target(ctx, readTarget);
   2923    struct gl_buffer_object *src = *src_ptr;
   2924 
   2925    struct gl_buffer_object **dst_ptr = get_buffer_target(ctx, writeTarget);
   2926    struct gl_buffer_object *dst = *dst_ptr;
   2927 
   2928    dst->MinMaxCacheDirty = true;
   2929    ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset,
   2930                                  size);
   2931 }
   2932 
   2933 void GLAPIENTRY
   2934 _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
   2935                         GLintptr readOffset, GLintptr writeOffset,
   2936                         GLsizeiptr size)
   2937 {
   2938    GET_CURRENT_CONTEXT(ctx);
   2939    struct gl_buffer_object *src, *dst;
   2940 
   2941    src = get_buffer(ctx, "glCopyBufferSubData", readTarget,
   2942                     GL_INVALID_OPERATION);
   2943    if (!src)
   2944       return;
   2945 
   2946    dst = get_buffer(ctx, "glCopyBufferSubData", writeTarget,
   2947                     GL_INVALID_OPERATION);
   2948    if (!dst)
   2949       return;
   2950 
   2951    copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size,
   2952                         "glCopyBufferSubData");
   2953 }
   2954 
   2955 void GLAPIENTRY
   2956 _mesa_CopyNamedBufferSubData_no_error(GLuint readBuffer, GLuint writeBuffer,
   2957                                       GLintptr readOffset,
   2958                                       GLintptr writeOffset, GLsizeiptr size)
   2959 {
   2960    GET_CURRENT_CONTEXT(ctx);
   2961 
   2962    struct gl_buffer_object *src = _mesa_lookup_bufferobj(ctx, readBuffer);
   2963    struct gl_buffer_object *dst = _mesa_lookup_bufferobj(ctx, writeBuffer);
   2964 
   2965    dst->MinMaxCacheDirty = true;
   2966    ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset,
   2967                                  size);
   2968 }
   2969 
   2970 void GLAPIENTRY
   2971 _mesa_CopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer,
   2972                              GLintptr readOffset, GLintptr writeOffset,
   2973                              GLsizeiptr size)
   2974 {
   2975    GET_CURRENT_CONTEXT(ctx);
   2976    struct gl_buffer_object *src, *dst;
   2977 
   2978    src = _mesa_lookup_bufferobj_err(ctx, readBuffer,
   2979                                     "glCopyNamedBufferSubData");
   2980    if (!src)
   2981       return;
   2982 
   2983    dst = _mesa_lookup_bufferobj_err(ctx, writeBuffer,
   2984                                     "glCopyNamedBufferSubData");
   2985    if (!dst)
   2986       return;
   2987 
   2988    copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size,
   2989                         "glCopyNamedBufferSubData");
   2990 }
   2991 
   2992 static bool
   2993 validate_map_buffer_range(struct gl_context *ctx,
   2994                           struct gl_buffer_object *bufObj, GLintptr offset,
   2995                           GLsizeiptr length, GLbitfield access,
   2996                           const char *func)
   2997 {
   2998    GLbitfield allowed_access;
   2999 
   3000    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, false);
   3001 
   3002    if (offset < 0) {
   3003       _mesa_error(ctx, GL_INVALID_VALUE,
   3004                   "%s(offset %ld < 0)", func, (long) offset);
   3005       return false;
   3006    }
   3007 
   3008    if (length < 0) {
   3009       _mesa_error(ctx, GL_INVALID_VALUE,
   3010                   "%s(length %ld < 0)", func, (long) length);
   3011       return false;
   3012    }
   3013 
   3014    /* Page 38 of the PDF of the OpenGL ES 3.0 spec says:
   3015     *
   3016     *     "An INVALID_OPERATION error is generated for any of the following
   3017     *     conditions:
   3018     *
   3019     *     * <length> is zero."
   3020     *
   3021     * Additionally, page 94 of the PDF of the OpenGL 4.5 core spec
   3022     * (30.10.2014) also says this, so it's no longer allowed for desktop GL,
   3023     * either.
   3024     */
   3025    if (length == 0) {
   3026       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(length = 0)", func);
   3027       return false;
   3028    }
   3029 
   3030    allowed_access = GL_MAP_READ_BIT |
   3031                     GL_MAP_WRITE_BIT |
   3032                     GL_MAP_INVALIDATE_RANGE_BIT |
   3033                     GL_MAP_INVALIDATE_BUFFER_BIT |
   3034                     GL_MAP_FLUSH_EXPLICIT_BIT |
   3035                     GL_MAP_UNSYNCHRONIZED_BIT;
   3036 
   3037    if (ctx->Extensions.ARB_buffer_storage) {
   3038          allowed_access |= GL_MAP_PERSISTENT_BIT |
   3039                            GL_MAP_COHERENT_BIT;
   3040    }
   3041 
   3042    if (access & ~allowed_access) {
   3043       /* generate an error if any bits other than those allowed are set */
   3044       _mesa_error(ctx, GL_INVALID_VALUE,
   3045                   "%s(access has undefined bits set)", func);
   3046       return false;
   3047    }
   3048 
   3049    if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) {
   3050       _mesa_error(ctx, GL_INVALID_OPERATION,
   3051                   "%s(access indicates neither read or write)", func);
   3052       return false;
   3053    }
   3054 
   3055    if ((access & GL_MAP_READ_BIT) &&
   3056        (access & (GL_MAP_INVALIDATE_RANGE_BIT |
   3057                   GL_MAP_INVALIDATE_BUFFER_BIT |
   3058                   GL_MAP_UNSYNCHRONIZED_BIT))) {
   3059       _mesa_error(ctx, GL_INVALID_OPERATION,
   3060                   "%s(read access with disallowed bits)", func);
   3061       return false;
   3062    }
   3063 
   3064    if ((access & GL_MAP_FLUSH_EXPLICIT_BIT) &&
   3065        ((access & GL_MAP_WRITE_BIT) == 0)) {
   3066       _mesa_error(ctx, GL_INVALID_OPERATION,
   3067                   "%s(access has flush explicit without write)", func);
   3068       return false;
   3069    }
   3070 
   3071    if (access & GL_MAP_READ_BIT &&
   3072        !(bufObj->StorageFlags & GL_MAP_READ_BIT)) {
   3073       _mesa_error(ctx, GL_INVALID_OPERATION,
   3074                   "%s(buffer does not allow read access)", func);
   3075       return false;
   3076    }
   3077 
   3078    if (access & GL_MAP_WRITE_BIT &&
   3079        !(bufObj->StorageFlags & GL_MAP_WRITE_BIT)) {
   3080       _mesa_error(ctx, GL_INVALID_OPERATION,
   3081                   "%s(buffer does not allow write access)", func);
   3082       return false;
   3083    }
   3084 
   3085    if (access & GL_MAP_COHERENT_BIT &&
   3086        !(bufObj->StorageFlags & GL_MAP_COHERENT_BIT)) {
   3087       _mesa_error(ctx, GL_INVALID_OPERATION,
   3088                   "%s(buffer does not allow coherent access)", func);
   3089       return false;
   3090    }
   3091 
   3092    if (access & GL_MAP_PERSISTENT_BIT &&
   3093        !(bufObj->StorageFlags & GL_MAP_PERSISTENT_BIT)) {
   3094       _mesa_error(ctx, GL_INVALID_OPERATION,
   3095                   "%s(buffer does not allow persistent access)", func);
   3096       return false;
   3097    }
   3098 
   3099    if (offset + length > bufObj->Size) {
   3100       _mesa_error(ctx, GL_INVALID_VALUE,
   3101                   "%s(offset %lu + length %lu > buffer_size %lu)", func,
   3102                   (unsigned long) offset, (unsigned long) length,
   3103                   (unsigned long) bufObj->Size);
   3104       return false;
   3105    }
   3106 
   3107    if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
   3108       _mesa_error(ctx, GL_INVALID_OPERATION,
   3109                   "%s(buffer already mapped)", func);
   3110       return false;
   3111    }
   3112 
   3113    if (access & GL_MAP_WRITE_BIT) {
   3114       bufObj->NumMapBufferWriteCalls++;
   3115       if ((bufObj->Usage == GL_STATIC_DRAW ||
   3116            bufObj->Usage == GL_STATIC_COPY) &&
   3117           bufObj->NumMapBufferWriteCalls >= BUFFER_WARNING_CALL_COUNT) {
   3118          BUFFER_USAGE_WARNING(ctx,
   3119                               "using %s(buffer %u, offset %u, length %u) to "
   3120                               "update a %s buffer",
   3121                               func, bufObj->Name, offset, length,
   3122                               _mesa_enum_to_string(bufObj->Usage));
   3123       }
   3124    }
   3125 
   3126    return true;
   3127 }
   3128 
   3129 static void *
   3130 map_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj,
   3131                  GLintptr offset, GLsizeiptr length, GLbitfield access,
   3132                  const char *func)
   3133 {
   3134    if (!bufObj->Size) {
   3135       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(buffer size = 0)", func);
   3136       return NULL;
   3137    }
   3138 
   3139    assert(ctx->Driver.MapBufferRange);
   3140    void *map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj,
   3141                                           MAP_USER);
   3142    if (!map) {
   3143       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(map failed)", func);
   3144    }
   3145    else {
   3146       /* The driver callback should have set all these fields.
   3147        * This is important because other modules (like VBO) might call
   3148        * the driver function directly.
   3149        */
   3150       assert(bufObj->Mappings[MAP_USER].Pointer == map);
   3151       assert(bufObj->Mappings[MAP_USER].Length == length);
   3152       assert(bufObj->Mappings[MAP_USER].Offset == offset);
   3153       assert(bufObj->Mappings[MAP_USER].AccessFlags == access);
   3154    }
   3155 
   3156    if (access & GL_MAP_WRITE_BIT) {
   3157       bufObj->Written = GL_TRUE;
   3158       bufObj->MinMaxCacheDirty = true;
   3159    }
   3160 
   3161 #ifdef VBO_DEBUG
   3162    if (strstr(func, "Range") == NULL) { /* If not MapRange */
   3163       printf("glMapBuffer(%u, sz %ld, access 0x%x)\n",
   3164             bufObj->Name, bufObj->Size, access);
   3165       /* Access must be write only */
   3166       if ((access & GL_MAP_WRITE_BIT) && (!(access & ~GL_MAP_WRITE_BIT))) {
   3167          GLuint i;
   3168          GLubyte *b = (GLubyte *) bufObj->Pointer;
   3169          for (i = 0; i < bufObj->Size; i++)
   3170             b[i] = i & 0xff;
   3171       }
   3172    }
   3173 #endif
   3174 
   3175 #ifdef BOUNDS_CHECK
   3176    if (strstr(func, "Range") == NULL) { /* If not MapRange */
   3177       GLubyte *buf = (GLubyte *) bufObj->Pointer;
   3178       GLuint i;
   3179       /* buffer is 100 bytes larger than requested, fill with magic value */
   3180       for (i = 0; i < 100; i++) {
   3181          buf[bufObj->Size - i - 1] = 123;
   3182       }
   3183    }
   3184 #endif
   3185 
   3186    return map;
   3187 }
   3188 
   3189 void * GLAPIENTRY
   3190 _mesa_MapBufferRange_no_error(GLenum target, GLintptr offset,
   3191                               GLsizeiptr length, GLbitfield access)
   3192 {
   3193    GET_CURRENT_CONTEXT(ctx);
   3194 
   3195    struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target);
   3196    struct gl_buffer_object *bufObj = *bufObjPtr;
   3197 
   3198    return map_buffer_range(ctx, bufObj, offset, length, access,
   3199                            "glMapBufferRange");
   3200 }
   3201 
   3202 void * GLAPIENTRY
   3203 _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
   3204                      GLbitfield access)
   3205 {
   3206    GET_CURRENT_CONTEXT(ctx);
   3207    struct gl_buffer_object *bufObj;
   3208 
   3209    if (!ctx->Extensions.ARB_map_buffer_range) {
   3210       _mesa_error(ctx, GL_INVALID_OPERATION,
   3211                   "glMapBufferRange(ARB_map_buffer_range not supported)");
   3212       return NULL;
   3213    }
   3214 
   3215    bufObj = get_buffer(ctx, "glMapBufferRange", target, GL_INVALID_OPERATION);
   3216    if (!bufObj)
   3217       return NULL;
   3218 
   3219    if (!validate_map_buffer_range(ctx, bufObj, offset, length, access,
   3220                                   "glMapBufferRange"))
   3221       return NULL;
   3222 
   3223    return map_buffer_range(ctx, bufObj, offset, length, access,
   3224                            "glMapBufferRange");
   3225 }
   3226 
   3227 void * GLAPIENTRY
   3228 _mesa_MapNamedBufferRange_no_error(GLuint buffer, GLintptr offset,
   3229                                    GLsizeiptr length, GLbitfield access)
   3230 {
   3231    GET_CURRENT_CONTEXT(ctx);
   3232    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   3233 
   3234    return map_buffer_range(ctx, bufObj, offset, length, access,
   3235                            "glMapNamedBufferRange");
   3236 }
   3237 
   3238 void * GLAPIENTRY
   3239 _mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length,
   3240                           GLbitfield access)
   3241 {
   3242    GET_CURRENT_CONTEXT(ctx);
   3243    struct gl_buffer_object *bufObj;
   3244 
   3245    if (!ctx->Extensions.ARB_map_buffer_range) {
   3246       _mesa_error(ctx, GL_INVALID_OPERATION,
   3247                   "glMapNamedBufferRange("
   3248                   "ARB_map_buffer_range not supported)");
   3249       return NULL;
   3250    }
   3251 
   3252    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMapNamedBufferRange");
   3253    if (!bufObj)
   3254       return NULL;
   3255 
   3256    if (!validate_map_buffer_range(ctx, bufObj, offset, length, access,
   3257                                   "glMapNamedBufferRange"))
   3258       return NULL;
   3259 
   3260    return map_buffer_range(ctx, bufObj, offset, length, access,
   3261                            "glMapNamedBufferRange");
   3262 }
   3263 
   3264 /**
   3265  * Converts GLenum access from MapBuffer and MapNamedBuffer into
   3266  * flags for input to map_buffer_range.
   3267  *
   3268  * \return true if the type of requested access is permissible.
   3269  */
   3270 static bool
   3271 get_map_buffer_access_flags(struct gl_context *ctx, GLenum access,
   3272                             GLbitfield *flags)
   3273 {
   3274    switch (access) {
   3275    case GL_READ_ONLY_ARB:
   3276       *flags = GL_MAP_READ_BIT;
   3277       return _mesa_is_desktop_gl(ctx);
   3278    case GL_WRITE_ONLY_ARB:
   3279       *flags = GL_MAP_WRITE_BIT;
   3280       return true;
   3281    case GL_READ_WRITE_ARB:
   3282       *flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
   3283       return _mesa_is_desktop_gl(ctx);
   3284    default:
   3285       *flags = 0;
   3286       return false;
   3287    }
   3288 }
   3289 
   3290 void * GLAPIENTRY
   3291 _mesa_MapBuffer_no_error(GLenum target, GLenum access)
   3292 {
   3293    GET_CURRENT_CONTEXT(ctx);
   3294 
   3295    GLbitfield accessFlags;
   3296    get_map_buffer_access_flags(ctx, access, &accessFlags);
   3297 
   3298    struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target);
   3299    struct gl_buffer_object *bufObj = *bufObjPtr;
   3300 
   3301    return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
   3302                            "glMapBuffer");
   3303 }
   3304 
   3305 void * GLAPIENTRY
   3306 _mesa_MapBuffer(GLenum target, GLenum access)
   3307 {
   3308    GET_CURRENT_CONTEXT(ctx);
   3309    struct gl_buffer_object *bufObj;
   3310    GLbitfield accessFlags;
   3311 
   3312    if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) {
   3313       _mesa_error(ctx, GL_INVALID_ENUM, "glMapBuffer(invalid access)");
   3314       return NULL;
   3315    }
   3316 
   3317    bufObj = get_buffer(ctx, "glMapBuffer", target, GL_INVALID_OPERATION);
   3318    if (!bufObj)
   3319       return NULL;
   3320 
   3321    if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
   3322                                   "glMapBuffer"))
   3323       return NULL;
   3324 
   3325    return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
   3326                            "glMapBuffer");
   3327 }
   3328 
   3329 void * GLAPIENTRY
   3330 _mesa_MapNamedBuffer_no_error(GLuint buffer, GLenum access)
   3331 {
   3332    GET_CURRENT_CONTEXT(ctx);
   3333 
   3334    GLbitfield accessFlags;
   3335    get_map_buffer_access_flags(ctx, access, &accessFlags);
   3336 
   3337    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   3338 
   3339    return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
   3340                            "glMapNamedBuffer");
   3341 }
   3342 
   3343 void * GLAPIENTRY
   3344 _mesa_MapNamedBuffer(GLuint buffer, GLenum access)
   3345 {
   3346    GET_CURRENT_CONTEXT(ctx);
   3347    struct gl_buffer_object *bufObj;
   3348    GLbitfield accessFlags;
   3349 
   3350    if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) {
   3351       _mesa_error(ctx, GL_INVALID_ENUM, "glMapNamedBuffer(invalid access)");
   3352       return NULL;
   3353    }
   3354 
   3355    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMapNamedBuffer");
   3356    if (!bufObj)
   3357       return NULL;
   3358 
   3359    if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
   3360                                   "glMapNamedBuffer"))
   3361       return NULL;
   3362 
   3363    return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
   3364                            "glMapNamedBuffer");
   3365 }
   3366 
   3367 
   3368 static void
   3369 flush_mapped_buffer_range(struct gl_context *ctx,
   3370                           struct gl_buffer_object *bufObj,
   3371                           GLintptr offset, GLsizeiptr length,
   3372                           const char *func)
   3373 {
   3374    if (!ctx->Extensions.ARB_map_buffer_range) {
   3375       _mesa_error(ctx, GL_INVALID_OPERATION,
   3376                   "%s(ARB_map_buffer_range not supported)", func);
   3377       return;
   3378    }
   3379 
   3380    if (offset < 0) {
   3381       _mesa_error(ctx, GL_INVALID_VALUE,
   3382                   "%s(offset %ld < 0)", func, (long) offset);
   3383       return;
   3384    }
   3385 
   3386    if (length < 0) {
   3387       _mesa_error(ctx, GL_INVALID_VALUE,
   3388                   "%s(length %ld < 0)", func, (long) length);
   3389       return;
   3390    }
   3391 
   3392    if (!_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
   3393       /* buffer is not mapped */
   3394       _mesa_error(ctx, GL_INVALID_OPERATION,
   3395                   "%s(buffer is not mapped)", func);
   3396       return;
   3397    }
   3398 
   3399    if ((bufObj->Mappings[MAP_USER].AccessFlags &
   3400         GL_MAP_FLUSH_EXPLICIT_BIT) == 0) {
   3401       _mesa_error(ctx, GL_INVALID_OPERATION,
   3402                   "%s(GL_MAP_FLUSH_EXPLICIT_BIT not set)", func);
   3403       return;
   3404    }
   3405 
   3406    if (offset + length > bufObj->Mappings[MAP_USER].Length) {
   3407       _mesa_error(ctx, GL_INVALID_VALUE,
   3408                   "%s(offset %ld + length %ld > mapped length %ld)", func,
   3409                   (long) offset, (long) length,
   3410                   (long) bufObj->Mappings[MAP_USER].Length);
   3411       return;
   3412    }
   3413 
   3414    assert(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_WRITE_BIT);
   3415 
   3416    if (ctx->Driver.FlushMappedBufferRange)
   3417       ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj,
   3418                                          MAP_USER);
   3419 }
   3420 
   3421 void GLAPIENTRY
   3422 _mesa_FlushMappedBufferRange_no_error(GLenum target, GLintptr offset,
   3423                                       GLsizeiptr length)
   3424 {
   3425    GET_CURRENT_CONTEXT(ctx);
   3426    struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target);
   3427    struct gl_buffer_object *bufObj = *bufObjPtr;
   3428 
   3429    if (ctx->Driver.FlushMappedBufferRange)
   3430       ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj,
   3431                                          MAP_USER);
   3432 }
   3433 
   3434 void GLAPIENTRY
   3435 _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset,
   3436                              GLsizeiptr length)
   3437 {
   3438    GET_CURRENT_CONTEXT(ctx);
   3439    struct gl_buffer_object *bufObj;
   3440 
   3441    bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target,
   3442                        GL_INVALID_OPERATION);
   3443    if (!bufObj)
   3444       return;
   3445 
   3446    flush_mapped_buffer_range(ctx, bufObj, offset, length,
   3447                              "glFlushMappedBufferRange");
   3448 }
   3449 
   3450 void GLAPIENTRY
   3451 _mesa_FlushMappedNamedBufferRange_no_error(GLuint buffer, GLintptr offset,
   3452                                            GLsizeiptr length)
   3453 {
   3454    GET_CURRENT_CONTEXT(ctx);
   3455    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   3456 
   3457    if (ctx->Driver.FlushMappedBufferRange)
   3458       ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj,
   3459                                          MAP_USER);
   3460 }
   3461 
   3462 void GLAPIENTRY
   3463 _mesa_FlushMappedNamedBufferRange(GLuint buffer, GLintptr offset,
   3464                                   GLsizeiptr length)
   3465 {
   3466    GET_CURRENT_CONTEXT(ctx);
   3467    struct gl_buffer_object *bufObj;
   3468 
   3469    bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
   3470                                        "glFlushMappedNamedBufferRange");
   3471    if (!bufObj)
   3472       return;
   3473 
   3474    flush_mapped_buffer_range(ctx, bufObj, offset, length,
   3475                              "glFlushMappedNamedBufferRange");
   3476 }
   3477 
   3478 static void
   3479 bind_buffer_range_uniform_buffer(struct gl_context *ctx, GLuint index,
   3480                                  struct gl_buffer_object *bufObj,
   3481                                  GLintptr offset, GLsizeiptr size)
   3482 {
   3483    if (bufObj == ctx->Shared->NullBufferObj) {
   3484       offset = -1;
   3485       size = -1;
   3486    }
   3487 
   3488    _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, bufObj);
   3489    bind_uniform_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
   3490 }
   3491 
   3492 /**
   3493  * Bind a region of a buffer object to a uniform block binding point.
   3494  * \param index  the uniform buffer binding point index
   3495  * \param bufObj  the buffer object
   3496  * \param offset  offset to the start of buffer object region
   3497  * \param size  size of the buffer object region
   3498  */
   3499 static void
   3500 bind_buffer_range_uniform_buffer_err(struct gl_context *ctx, GLuint index,
   3501                                      struct gl_buffer_object *bufObj,
   3502                                      GLintptr offset, GLsizeiptr size)
   3503 {
   3504    if (index >= ctx->Const.MaxUniformBufferBindings) {
   3505       _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
   3506       return;
   3507    }
   3508 
   3509    if (offset & (ctx->Const.UniformBufferOffsetAlignment - 1)) {
   3510       _mesa_error(ctx, GL_INVALID_VALUE,
   3511                   "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
   3512 		  ctx->Const.UniformBufferOffsetAlignment);
   3513       return;
   3514    }
   3515 
   3516    bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
   3517 }
   3518 
   3519 static void
   3520 bind_buffer_range_shader_storage_buffer(struct gl_context *ctx,
   3521                                         GLuint index,
   3522                                         struct gl_buffer_object *bufObj,
   3523                                         GLintptr offset,
   3524                                         GLsizeiptr size)
   3525 {
   3526    if (bufObj == ctx->Shared->NullBufferObj) {
   3527       offset = -1;
   3528       size = -1;
   3529    }
   3530 
   3531    _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, bufObj);
   3532    bind_shader_storage_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
   3533 }
   3534 
   3535 /**
   3536  * Bind a region of a buffer object to a shader storage block binding point.
   3537  * \param index  the shader storage buffer binding point index
   3538  * \param bufObj  the buffer object
   3539  * \param offset  offset to the start of buffer object region
   3540  * \param size  size of the buffer object region
   3541  */
   3542 static void
   3543 bind_buffer_range_shader_storage_buffer_err(struct gl_context *ctx,
   3544                                             GLuint index,
   3545                                             struct gl_buffer_object *bufObj,
   3546                                             GLintptr offset, GLsizeiptr size)
   3547 {
   3548    if (index >= ctx->Const.MaxShaderStorageBufferBindings) {
   3549       _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
   3550       return;
   3551    }
   3552 
   3553    if (offset & (ctx->Const.ShaderStorageBufferOffsetAlignment - 1)) {
   3554       _mesa_error(ctx, GL_INVALID_VALUE,
   3555                   "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
   3556                   ctx->Const.ShaderStorageBufferOffsetAlignment);
   3557       return;
   3558    }
   3559 
   3560    bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset, size);
   3561 }
   3562 
   3563 static void
   3564 bind_buffer_range_atomic_buffer(struct gl_context *ctx, GLuint index,
   3565                                  struct gl_buffer_object *bufObj,
   3566                                  GLintptr offset, GLsizeiptr size)
   3567 {
   3568    if (bufObj == ctx->Shared->NullBufferObj) {
   3569       offset = -1;
   3570       size = -1;
   3571    }
   3572 
   3573    _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
   3574    bind_atomic_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
   3575 }
   3576 
   3577 /**
   3578  * Bind a region of a buffer object to an atomic storage block binding point.
   3579  * \param index  the shader storage buffer binding point index
   3580  * \param bufObj  the buffer object
   3581  * \param offset  offset to the start of buffer object region
   3582  * \param size  size of the buffer object region
   3583  */
   3584 static void
   3585 bind_buffer_range_atomic_buffer_err(struct gl_context *ctx,
   3586                                     GLuint index,
   3587                                     struct gl_buffer_object *bufObj,
   3588                                     GLintptr offset, GLsizeiptr size)
   3589 {
   3590    if (index >= ctx->Const.MaxAtomicBufferBindings) {
   3591       _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
   3592       return;
   3593    }
   3594 
   3595    if (offset & (ATOMIC_COUNTER_SIZE - 1)) {
   3596       _mesa_error(ctx, GL_INVALID_VALUE,
   3597 		  "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
   3598 		  ATOMIC_COUNTER_SIZE);
   3599       return;
   3600    }
   3601 
   3602    bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size);
   3603 }
   3604 
   3605 static inline bool
   3606 bind_buffers_check_offset_and_size(struct gl_context *ctx,
   3607                                    GLuint index,
   3608                                    const GLintptr *offsets,
   3609                                    const GLsizeiptr *sizes)
   3610 {
   3611    if (offsets[index] < 0) {
   3612       /* The ARB_multi_bind spec says:
   3613        *
   3614        *    "An INVALID_VALUE error is generated by BindBuffersRange if any
   3615        *     value in <offsets> is less than zero (per binding)."
   3616        */
   3617       _mesa_error(ctx, GL_INVALID_VALUE,
   3618                   "glBindBuffersRange(offsets[%u]=%" PRId64 " < 0)",
   3619                   index, (int64_t) offsets[index]);
   3620       return false;
   3621    }
   3622 
   3623    if (sizes[index] <= 0) {
   3624       /* The ARB_multi_bind spec says:
   3625        *
   3626        *     "An INVALID_VALUE error is generated by BindBuffersRange if any
   3627        *      value in <sizes> is less than or equal to zero (per binding)."
   3628        */
   3629       _mesa_error(ctx, GL_INVALID_VALUE,
   3630                   "glBindBuffersRange(sizes[%u]=%" PRId64 " <= 0)",
   3631                   index, (int64_t) sizes[index]);
   3632       return false;
   3633    }
   3634 
   3635    return true;
   3636 }
   3637 
   3638 static bool
   3639 error_check_bind_uniform_buffers(struct gl_context *ctx,
   3640                                  GLuint first, GLsizei count,
   3641                                  const char *caller)
   3642 {
   3643    if (!ctx->Extensions.ARB_uniform_buffer_object) {
   3644       _mesa_error(ctx, GL_INVALID_ENUM,
   3645                   "%s(target=GL_UNIFORM_BUFFER)", caller);
   3646       return false;
   3647    }
   3648 
   3649    /* The ARB_multi_bind_spec says:
   3650     *
   3651     *     "An INVALID_OPERATION error is generated if <first> + <count> is
   3652     *      greater than the number of target-specific indexed binding points,
   3653     *      as described in section 6.7.1."
   3654     */
   3655    if (first + count > ctx->Const.MaxUniformBufferBindings) {
   3656       _mesa_error(ctx, GL_INVALID_OPERATION,
   3657                   "%s(first=%u + count=%d > the value of "
   3658                   "GL_MAX_UNIFORM_BUFFER_BINDINGS=%u)",
   3659                   caller, first, count,
   3660                   ctx->Const.MaxUniformBufferBindings);
   3661       return false;
   3662    }
   3663 
   3664    return true;
   3665 }
   3666 
   3667 static bool
   3668 error_check_bind_shader_storage_buffers(struct gl_context *ctx,
   3669                                         GLuint first, GLsizei count,
   3670                                         const char *caller)
   3671 {
   3672    if (!ctx->Extensions.ARB_shader_storage_buffer_object) {
   3673       _mesa_error(ctx, GL_INVALID_ENUM,
   3674                   "%s(target=GL_SHADER_STORAGE_BUFFER)", caller);
   3675       return false;
   3676    }
   3677 
   3678    /* The ARB_multi_bind_spec says:
   3679     *
   3680     *     "An INVALID_OPERATION error is generated if <first> + <count> is
   3681     *      greater than the number of target-specific indexed binding points,
   3682     *      as described in section 6.7.1."
   3683     */
   3684    if (first + count > ctx->Const.MaxShaderStorageBufferBindings) {
   3685       _mesa_error(ctx, GL_INVALID_OPERATION,
   3686                   "%s(first=%u + count=%d > the value of "
   3687                   "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS=%u)",
   3688                   caller, first, count,
   3689                   ctx->Const.MaxShaderStorageBufferBindings);
   3690       return false;
   3691    }
   3692 
   3693    return true;
   3694 }
   3695 
   3696 /**
   3697  * Unbind all uniform buffers in the range
   3698  * <first> through <first>+<count>-1
   3699  */
   3700 static void
   3701 unbind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count)
   3702 {
   3703    struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj;
   3704 
   3705    for (int i = 0; i < count; i++)
   3706       set_buffer_binding(ctx, &ctx->UniformBufferBindings[first + i],
   3707                          bufObj, -1, -1, GL_TRUE, 0);
   3708 }
   3709 
   3710 /**
   3711  * Unbind all shader storage buffers in the range
   3712  * <first> through <first>+<count>-1
   3713  */
   3714 static void
   3715 unbind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
   3716                               GLsizei count)
   3717 {
   3718    struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj;
   3719 
   3720    for (int i = 0; i < count; i++)
   3721       set_buffer_binding(ctx, &ctx->ShaderStorageBufferBindings[first + i],
   3722                          bufObj, -1, -1, GL_TRUE, 0);
   3723 }
   3724 
   3725 static void
   3726 bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count,
   3727                      const GLuint *buffers,
   3728                      bool range,
   3729                      const GLintptr *offsets, const GLsizeiptr *sizes,
   3730                      const char *caller)
   3731 {
   3732    if (!error_check_bind_uniform_buffers(ctx, first, count, caller))
   3733       return;
   3734 
   3735    /* Assume that at least one binding will be changed */
   3736    FLUSH_VERTICES(ctx, 0);
   3737    ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
   3738 
   3739    if (!buffers) {
   3740       /* The ARB_multi_bind spec says:
   3741        *
   3742        *    "If <buffers> is NULL, all bindings from <first> through
   3743        *     <first>+<count>-1 are reset to their unbound (zero) state.
   3744        *     In this case, the offsets and sizes associated with the
   3745        *     binding points are set to default values, ignoring
   3746        *     <offsets> and <sizes>."
   3747        */
   3748       unbind_uniform_buffers(ctx, first, count);
   3749       return;
   3750    }
   3751 
   3752    /* Note that the error semantics for multi-bind commands differ from
   3753     * those of other GL commands.
   3754     *
   3755     * The Issues section in the ARB_multi_bind spec says:
   3756     *
   3757     *    "(11) Typically, OpenGL specifies that if an error is generated by a
   3758     *          command, that command has no effect.  This is somewhat
   3759     *          unfortunate for multi-bind commands, because it would require a
   3760     *          first pass to scan the entire list of bound objects for errors
   3761     *          and then a second pass to actually perform the bindings.
   3762     *          Should we have different error semantics?
   3763     *
   3764     *       RESOLVED:  Yes.  In this specification, when the parameters for
   3765     *       one of the <count> binding points are invalid, that binding point
   3766     *       is not updated and an error will be generated.  However, other
   3767     *       binding points in the same command will be updated if their
   3768     *       parameters are valid and no other error occurs."
   3769     */
   3770 
   3771    _mesa_HashLockMutex(ctx->Shared->BufferObjects);
   3772 
   3773    for (int i = 0; i < count; i++) {
   3774       struct gl_buffer_binding *binding =
   3775          &ctx->UniformBufferBindings[first + i];
   3776       GLintptr offset = 0;
   3777       GLsizeiptr size = 0;
   3778 
   3779       if (range) {
   3780          if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
   3781             continue;
   3782 
   3783          /* The ARB_multi_bind spec says:
   3784           *
   3785           *     "An INVALID_VALUE error is generated by BindBuffersRange if any
   3786           *      pair of values in <offsets> and <sizes> does not respectively
   3787           *      satisfy the constraints described for those parameters for the
   3788           *      specified target, as described in section 6.7.1 (per binding)."
   3789           *
   3790           * Section 6.7.1 refers to table 6.5, which says:
   3791           *
   3792           *     "
   3793           *       Uniform buffer array bindings (see sec. 7.6)                  
   3794           *      
   3795           *        ...                  ...                                    
   3796           *        offset restriction   multiple of value of UNIFORM_BUFFER_-  
   3797           *                             OFFSET_ALIGNMENT                       
   3798           *        ...                  ...                                    
   3799           *        size restriction     none                                   
   3800           *      "
   3801           */
   3802          if (offsets[i] & (ctx->Const.UniformBufferOffsetAlignment - 1)) {
   3803             _mesa_error(ctx, GL_INVALID_VALUE,
   3804                         "glBindBuffersRange(offsets[%u]=%" PRId64
   3805                         " is misaligned; it must be a multiple of the value of "
   3806                         "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT=%u when "
   3807                         "target=GL_UNIFORM_BUFFER)",
   3808                         i, (int64_t) offsets[i],
   3809                         ctx->Const.UniformBufferOffsetAlignment);
   3810             continue;
   3811          }
   3812 
   3813          offset = offsets[i];
   3814          size = sizes[i];
   3815       }
   3816 
   3817       set_buffer_multi_binding(ctx, buffers, i, caller,
   3818                                binding, offset, size, range,
   3819                                USAGE_UNIFORM_BUFFER);
   3820    }
   3821 
   3822    _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   3823 }
   3824 
   3825 static void
   3826 bind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
   3827                             GLsizei count, const GLuint *buffers,
   3828                             bool range,
   3829                             const GLintptr *offsets,
   3830                             const GLsizeiptr *sizes,
   3831                             const char *caller)
   3832 {
   3833    if (!error_check_bind_shader_storage_buffers(ctx, first, count, caller))
   3834       return;
   3835 
   3836    /* Assume that at least one binding will be changed */
   3837    FLUSH_VERTICES(ctx, 0);
   3838    ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
   3839 
   3840    if (!buffers) {
   3841       /* The ARB_multi_bind spec says:
   3842        *
   3843        *    "If <buffers> is NULL, all bindings from <first> through
   3844        *     <first>+<count>-1 are reset to their unbound (zero) state.
   3845        *     In this case, the offsets and sizes associated with the
   3846        *     binding points are set to default values, ignoring
   3847        *     <offsets> and <sizes>."
   3848        */
   3849       unbind_shader_storage_buffers(ctx, first, count);
   3850       return;
   3851    }
   3852 
   3853    /* Note that the error semantics for multi-bind commands differ from
   3854     * those of other GL commands.
   3855     *
   3856     * The Issues section in the ARB_multi_bind spec says:
   3857     *
   3858     *    "(11) Typically, OpenGL specifies that if an error is generated by a
   3859     *          command, that command has no effect.  This is somewhat
   3860     *          unfortunate for multi-bind commands, because it would require a
   3861     *          first pass to scan the entire list of bound objects for errors
   3862     *          and then a second pass to actually perform the bindings.
   3863     *          Should we have different error semantics?
   3864     *
   3865     *       RESOLVED:  Yes.  In this specification, when the parameters for
   3866     *       one of the <count> binding points are invalid, that binding point
   3867     *       is not updated and an error will be generated.  However, other
   3868     *       binding points in the same command will be updated if their
   3869     *       parameters are valid and no other error occurs."
   3870     */
   3871 
   3872    _mesa_HashLockMutex(ctx->Shared->BufferObjects);
   3873 
   3874    for (int i = 0; i < count; i++) {
   3875       struct gl_buffer_binding *binding =
   3876          &ctx->ShaderStorageBufferBindings[first + i];
   3877       GLintptr offset = 0;
   3878       GLsizeiptr size = 0;
   3879 
   3880       if (range) {
   3881          if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
   3882             continue;
   3883 
   3884          /* The ARB_multi_bind spec says:
   3885          *
   3886          *     "An INVALID_VALUE error is generated by BindBuffersRange if any
   3887          *      pair of values in <offsets> and <sizes> does not respectively
   3888          *      satisfy the constraints described for those parameters for the
   3889          *      specified target, as described in section 6.7.1 (per binding)."
   3890          *
   3891          * Section 6.7.1 refers to table 6.5, which says:
   3892          *
   3893          *     "
   3894          *       Shader storage buffer array bindings (see sec. 7.8)           
   3895          *      
   3896          *        ...                  ...                                    
   3897          *        offset restriction   multiple of value of SHADER_STORAGE_-  
   3898          *                             BUFFER_OFFSET_ALIGNMENT                
   3899          *        ...                  ...                                    
   3900          *        size restriction     none                                   
   3901          *      "
   3902          */
   3903          if (offsets[i] & (ctx->Const.ShaderStorageBufferOffsetAlignment - 1)) {
   3904             _mesa_error(ctx, GL_INVALID_VALUE,
   3905                         "glBindBuffersRange(offsets[%u]=%" PRId64
   3906                         " is misaligned; it must be a multiple of the value of "
   3907                         "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT=%u when "
   3908                         "target=GL_SHADER_STORAGE_BUFFER)",
   3909                         i, (int64_t) offsets[i],
   3910                         ctx->Const.ShaderStorageBufferOffsetAlignment);
   3911             continue;
   3912          }
   3913 
   3914          offset = offsets[i];
   3915          size = sizes[i];
   3916       }
   3917 
   3918       set_buffer_multi_binding(ctx, buffers, i, caller,
   3919                                binding, offset, size, range,
   3920                                USAGE_SHADER_STORAGE_BUFFER);
   3921    }
   3922 
   3923    _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   3924 }
   3925 
   3926 static bool
   3927 error_check_bind_xfb_buffers(struct gl_context *ctx,
   3928                              struct gl_transform_feedback_object *tfObj,
   3929                              GLuint first, GLsizei count, const char *caller)
   3930 {
   3931    if (!ctx->Extensions.EXT_transform_feedback) {
   3932       _mesa_error(ctx, GL_INVALID_ENUM,
   3933                   "%s(target=GL_TRANSFORM_FEEDBACK_BUFFER)", caller);
   3934       return false;
   3935    }
   3936 
   3937    /* Page 398 of the PDF of the OpenGL 4.4 (Core Profile) spec says:
   3938     *
   3939     *     "An INVALID_OPERATION error is generated :
   3940     *
   3941     *     ...
   3942     *      by BindBufferRange or BindBufferBase if target is TRANSFORM_-
   3943     *       FEEDBACK_BUFFER and transform feedback is currently active."
   3944     *
   3945     * We assume that this is also meant to apply to BindBuffersRange
   3946     * and BindBuffersBase.
   3947     */
   3948    if (tfObj->Active) {
   3949       _mesa_error(ctx, GL_INVALID_OPERATION,
   3950                   "%s(Changing transform feedback buffers while "
   3951                   "transform feedback is active)", caller);
   3952       return false;
   3953    }
   3954 
   3955    /* The ARB_multi_bind_spec says:
   3956     *
   3957     *     "An INVALID_OPERATION error is generated if <first> + <count> is
   3958     *      greater than the number of target-specific indexed binding points,
   3959     *      as described in section 6.7.1."
   3960     */
   3961    if (first + count > ctx->Const.MaxTransformFeedbackBuffers) {
   3962       _mesa_error(ctx, GL_INVALID_OPERATION,
   3963                   "%s(first=%u + count=%d > the value of "
   3964                   "GL_MAX_TRANSFORM_FEEDBACK_BUFFERS=%u)",
   3965                   caller, first, count,
   3966                   ctx->Const.MaxTransformFeedbackBuffers);
   3967       return false;
   3968    }
   3969 
   3970    return true;
   3971 }
   3972 
   3973 /**
   3974  * Unbind all transform feedback buffers in the range
   3975  * <first> through <first>+<count>-1
   3976  */
   3977 static void
   3978 unbind_xfb_buffers(struct gl_context *ctx,
   3979                    struct gl_transform_feedback_object *tfObj,
   3980                    GLuint first, GLsizei count)
   3981 {
   3982    struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj;
   3983 
   3984    for (int i = 0; i < count; i++)
   3985       _mesa_set_transform_feedback_binding(ctx, tfObj, first + i,
   3986                                            bufObj, 0, 0);
   3987 }
   3988 
   3989 static void
   3990 bind_xfb_buffers(struct gl_context *ctx,
   3991                  GLuint first, GLsizei count,
   3992                  const GLuint *buffers,
   3993                  bool range,
   3994                  const GLintptr *offsets,
   3995                  const GLsizeiptr *sizes,
   3996                  const char *caller)
   3997 {
   3998    struct gl_transform_feedback_object *tfObj =
   3999        ctx->TransformFeedback.CurrentObject;
   4000 
   4001    if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, caller))
   4002       return;
   4003 
   4004    /* Assume that at least one binding will be changed */
   4005    FLUSH_VERTICES(ctx, 0);
   4006    ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback;
   4007 
   4008    if (!buffers) {
   4009       /* The ARB_multi_bind spec says:
   4010        *
   4011        *    "If <buffers> is NULL, all bindings from <first> through
   4012        *     <first>+<count>-1 are reset to their unbound (zero) state.
   4013        *     In this case, the offsets and sizes associated with the
   4014        *     binding points are set to default values, ignoring
   4015        *     <offsets> and <sizes>."
   4016        */
   4017       unbind_xfb_buffers(ctx, tfObj, first, count);
   4018       return;
   4019    }
   4020 
   4021    /* Note that the error semantics for multi-bind commands differ from
   4022     * those of other GL commands.
   4023     *
   4024     * The Issues section in the ARB_multi_bind spec says:
   4025     *
   4026     *    "(11) Typically, OpenGL specifies that if an error is generated by a
   4027     *          command, that command has no effect.  This is somewhat
   4028     *          unfortunate for multi-bind commands, because it would require a
   4029     *          first pass to scan the entire list of bound objects for errors
   4030     *          and then a second pass to actually perform the bindings.
   4031     *          Should we have different error semantics?
   4032     *
   4033     *       RESOLVED:  Yes.  In this specification, when the parameters for
   4034     *       one of the <count> binding points are invalid, that binding point
   4035     *       is not updated and an error will be generated.  However, other
   4036     *       binding points in the same command will be updated if their
   4037     *       parameters are valid and no other error occurs."
   4038     */
   4039 
   4040    _mesa_HashLockMutex(ctx->Shared->BufferObjects);
   4041 
   4042    for (int i = 0; i < count; i++) {
   4043       const GLuint index = first + i;
   4044       struct gl_buffer_object * const boundBufObj = tfObj->Buffers[index];
   4045       struct gl_buffer_object *bufObj;
   4046       GLintptr offset = 0;
   4047       GLsizeiptr size = 0;
   4048 
   4049       if (range) {
   4050          if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
   4051             continue;
   4052 
   4053          /* The ARB_multi_bind spec says:
   4054           *
   4055           *     "An INVALID_VALUE error is generated by BindBuffersRange if any
   4056           *      pair of values in <offsets> and <sizes> does not respectively
   4057           *      satisfy the constraints described for those parameters for the
   4058           *      specified target, as described in section 6.7.1 (per binding)."
   4059           *
   4060           * Section 6.7.1 refers to table 6.5, which says:
   4061           *
   4062           *     "
   4063           *       Transform feedback array bindings (see sec. 13.2.2)           
   4064           *      
   4065           *          ...                    ...                                
   4066           *          offset restriction     multiple of 4                      
   4067           *          ...                    ...                                
   4068           *          size restriction       multiple of 4                      
   4069           *      "
   4070           */
   4071          if (offsets[i] & 0x3) {
   4072             _mesa_error(ctx, GL_INVALID_VALUE,
   4073                         "glBindBuffersRange(offsets[%u]=%" PRId64
   4074                         " is misaligned; it must be a multiple of 4 when "
   4075                         "target=GL_TRANSFORM_FEEDBACK_BUFFER)",
   4076                         i, (int64_t) offsets[i]);
   4077             continue;
   4078          }
   4079 
   4080          if (sizes[i] & 0x3) {
   4081             _mesa_error(ctx, GL_INVALID_VALUE,
   4082                         "glBindBuffersRange(sizes[%u]=%" PRId64
   4083                         " is misaligned; it must be a multiple of 4 when "
   4084                         "target=GL_TRANSFORM_FEEDBACK_BUFFER)",
   4085                         i, (int64_t) sizes[i]);
   4086             continue;
   4087          }
   4088 
   4089          offset = offsets[i];
   4090          size = sizes[i];
   4091       }
   4092 
   4093       if (boundBufObj && boundBufObj->Name == buffers[i])
   4094          bufObj = boundBufObj;
   4095       else
   4096          bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller);
   4097 
   4098       if (bufObj)
   4099          _mesa_set_transform_feedback_binding(ctx, tfObj, index, bufObj,
   4100                                               offset, size);
   4101    }
   4102 
   4103    _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   4104 }
   4105 
   4106 static bool
   4107 error_check_bind_atomic_buffers(struct gl_context *ctx,
   4108                                 GLuint first, GLsizei count,
   4109                                 const char *caller)
   4110 {
   4111    if (!ctx->Extensions.ARB_shader_atomic_counters) {
   4112       _mesa_error(ctx, GL_INVALID_ENUM,
   4113                   "%s(target=GL_ATOMIC_COUNTER_BUFFER)", caller);
   4114       return false;
   4115    }
   4116 
   4117    /* The ARB_multi_bind_spec says:
   4118     *
   4119     *     "An INVALID_OPERATION error is generated if <first> + <count> is
   4120     *      greater than the number of target-specific indexed binding points,
   4121     *      as described in section 6.7.1."
   4122     */
   4123    if (first + count > ctx->Const.MaxAtomicBufferBindings) {
   4124       _mesa_error(ctx, GL_INVALID_OPERATION,
   4125                   "%s(first=%u + count=%d > the value of "
   4126                   "GL_MAX_ATOMIC_BUFFER_BINDINGS=%u)",
   4127                   caller, first, count, ctx->Const.MaxAtomicBufferBindings);
   4128       return false;
   4129    }
   4130 
   4131    return true;
   4132 }
   4133 
   4134 /**
   4135  * Unbind all atomic counter buffers in the range
   4136  * <first> through <first>+<count>-1
   4137  */
   4138 static void
   4139 unbind_atomic_buffers(struct gl_context *ctx, GLuint first, GLsizei count)
   4140 {
   4141    struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj;
   4142 
   4143    for (int i = 0; i < count; i++)
   4144       set_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i],
   4145                          bufObj, -1, -1, GL_TRUE, 0);
   4146 }
   4147 
   4148 static void
   4149 bind_atomic_buffers(struct gl_context *ctx,
   4150                     GLuint first,
   4151                     GLsizei count,
   4152                     const GLuint *buffers,
   4153                     bool range,
   4154                     const GLintptr *offsets,
   4155                     const GLsizeiptr *sizes,
   4156                     const char *caller)
   4157 {
   4158    if (!error_check_bind_atomic_buffers(ctx, first, count, caller))
   4159      return;
   4160 
   4161    /* Assume that at least one binding will be changed */
   4162    FLUSH_VERTICES(ctx, 0);
   4163    ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
   4164 
   4165    if (!buffers) {
   4166       /* The ARB_multi_bind spec says:
   4167        *
   4168        *    "If <buffers> is NULL, all bindings from <first> through
   4169        *     <first>+<count>-1 are reset to their unbound (zero) state.
   4170        *     In this case, the offsets and sizes associated with the
   4171        *     binding points are set to default values, ignoring
   4172        *     <offsets> and <sizes>."
   4173        */
   4174       unbind_atomic_buffers(ctx, first, count);
   4175       return;
   4176    }
   4177 
   4178    /* Note that the error semantics for multi-bind commands differ from
   4179     * those of other GL commands.
   4180     *
   4181     * The Issues section in the ARB_multi_bind spec says:
   4182     *
   4183     *    "(11) Typically, OpenGL specifies that if an error is generated by a
   4184     *          command, that command has no effect.  This is somewhat
   4185     *          unfortunate for multi-bind commands, because it would require a
   4186     *          first pass to scan the entire list of bound objects for errors
   4187     *          and then a second pass to actually perform the bindings.
   4188     *          Should we have different error semantics?
   4189     *
   4190     *       RESOLVED:  Yes.  In this specification, when the parameters for
   4191     *       one of the <count> binding points are invalid, that binding point
   4192     *       is not updated and an error will be generated.  However, other
   4193     *       binding points in the same command will be updated if their
   4194     *       parameters are valid and no other error occurs."
   4195     */
   4196 
   4197    _mesa_HashLockMutex(ctx->Shared->BufferObjects);
   4198 
   4199    for (int i = 0; i < count; i++) {
   4200       struct gl_buffer_binding *binding =
   4201          &ctx->AtomicBufferBindings[first + i];
   4202       GLintptr offset = 0;
   4203       GLsizeiptr size = 0;
   4204 
   4205       if (range) {
   4206          if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
   4207             continue;
   4208 
   4209          /* The ARB_multi_bind spec says:
   4210           *
   4211           *     "An INVALID_VALUE error is generated by BindBuffersRange if any
   4212           *      pair of values in <offsets> and <sizes> does not respectively
   4213           *      satisfy the constraints described for those parameters for the
   4214           *      specified target, as described in section 6.7.1 (per binding)."
   4215           *
   4216           * Section 6.7.1 refers to table 6.5, which says:
   4217           *
   4218           *     "
   4219           *       Atomic counter array bindings (see sec. 7.7.2)                
   4220           *      
   4221           *          ...                    ...                                
   4222           *          offset restriction     multiple of 4                      
   4223           *          ...                    ...                                
   4224           *          size restriction       none                               
   4225           *      "
   4226           */
   4227          if (offsets[i] & (ATOMIC_COUNTER_SIZE - 1)) {
   4228             _mesa_error(ctx, GL_INVALID_VALUE,
   4229                         "glBindBuffersRange(offsets[%u]=%" PRId64
   4230                         " is misaligned; it must be a multiple of %d when "
   4231                         "target=GL_ATOMIC_COUNTER_BUFFER)",
   4232                         i, (int64_t) offsets[i], ATOMIC_COUNTER_SIZE);
   4233             continue;
   4234          }
   4235 
   4236          offset = offsets[i];
   4237          size = sizes[i];
   4238       }
   4239 
   4240       set_buffer_multi_binding(ctx, buffers, i, caller,
   4241                                binding, offset, size, range,
   4242                                USAGE_ATOMIC_COUNTER_BUFFER);
   4243    }
   4244 
   4245    _mesa_HashUnlockMutex(ctx->Shared->BufferObjects);
   4246 }
   4247 
   4248 static ALWAYS_INLINE void
   4249 bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset,
   4250                   GLsizeiptr size, bool no_error)
   4251 {
   4252    GET_CURRENT_CONTEXT(ctx);
   4253    struct gl_buffer_object *bufObj;
   4254 
   4255    if (MESA_VERBOSE & VERBOSE_API) {
   4256       _mesa_debug(ctx, "glBindBufferRange(%s, %u, %u, %lu, %lu)\n",
   4257                   _mesa_enum_to_string(target), index, buffer,
   4258                   (unsigned long) offset, (unsigned long) size);
   4259    }
   4260 
   4261    if (buffer == 0) {
   4262       bufObj = ctx->Shared->NullBufferObj;
   4263    } else {
   4264       bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   4265       if (!_mesa_handle_bind_buffer_gen(ctx, buffer,
   4266                                         &bufObj, "glBindBufferRange"))
   4267          return;
   4268 
   4269       if (!no_error && !bufObj) {
   4270          _mesa_error(ctx, GL_INVALID_OPERATION,
   4271                      "glBindBufferRange(invalid buffer=%u)", buffer);
   4272          return;
   4273       }
   4274    }
   4275 
   4276    if (no_error) {
   4277       switch (target) {
   4278       case GL_TRANSFORM_FEEDBACK_BUFFER:
   4279          _mesa_bind_buffer_range_xfb(ctx, ctx->TransformFeedback.CurrentObject,
   4280                                      index, bufObj, offset, size);
   4281          return;
   4282       case GL_UNIFORM_BUFFER:
   4283          bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
   4284          return;
   4285       case GL_SHADER_STORAGE_BUFFER:
   4286          bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset,
   4287                                                  size);
   4288          return;
   4289       case GL_ATOMIC_COUNTER_BUFFER:
   4290          bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size);
   4291          return;
   4292       default:
   4293          unreachable("invalid BindBufferRange target with KHR_no_error");
   4294       }
   4295    } else {
   4296       if (buffer != 0) {
   4297          if (size <= 0) {
   4298             _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
   4299                         (int) size);
   4300             return;
   4301          }
   4302       }
   4303 
   4304       switch (target) {
   4305       case GL_TRANSFORM_FEEDBACK_BUFFER:
   4306          if (!_mesa_validate_buffer_range_xfb(ctx,
   4307                                               ctx->TransformFeedback.CurrentObject,
   4308                                               index, bufObj, offset, size,
   4309                                               false))
   4310             return;
   4311 
   4312          _mesa_bind_buffer_range_xfb(ctx, ctx->TransformFeedback.CurrentObject,
   4313                                      index, bufObj, offset, size);
   4314          return;
   4315       case GL_UNIFORM_BUFFER:
   4316          bind_buffer_range_uniform_buffer_err(ctx, index, bufObj, offset,
   4317                                               size);
   4318          return;
   4319       case GL_SHADER_STORAGE_BUFFER:
   4320          bind_buffer_range_shader_storage_buffer_err(ctx, index, bufObj,
   4321                                                      offset, size);
   4322          return;
   4323       case GL_ATOMIC_COUNTER_BUFFER:
   4324          bind_buffer_range_atomic_buffer_err(ctx, index, bufObj,
   4325                                              offset, size);
   4326          return;
   4327       default:
   4328          _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
   4329          return;
   4330       }
   4331    }
   4332 }
   4333 
   4334 void GLAPIENTRY
   4335 _mesa_BindBufferRange_no_error(GLenum target, GLuint index, GLuint buffer,
   4336                                GLintptr offset, GLsizeiptr size)
   4337 {
   4338    bind_buffer_range(target, index, buffer, offset, size, true);
   4339 }
   4340 
   4341 void GLAPIENTRY
   4342 _mesa_BindBufferRange(GLenum target, GLuint index,
   4343                       GLuint buffer, GLintptr offset, GLsizeiptr size)
   4344 {
   4345    bind_buffer_range(target, index, buffer, offset, size, false);
   4346 }
   4347 
   4348 void GLAPIENTRY
   4349 _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
   4350 {
   4351    GET_CURRENT_CONTEXT(ctx);
   4352    struct gl_buffer_object *bufObj;
   4353 
   4354    if (MESA_VERBOSE & VERBOSE_API) {
   4355       _mesa_debug(ctx, "glBindBufferBase(%s, %u, %u)\n",
   4356                   _mesa_enum_to_string(target), index, buffer);
   4357    }
   4358 
   4359    if (buffer == 0) {
   4360       bufObj = ctx->Shared->NullBufferObj;
   4361    } else {
   4362       bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   4363       if (!_mesa_handle_bind_buffer_gen(ctx, buffer,
   4364                                         &bufObj, "glBindBufferBase"))
   4365          return;
   4366 
   4367       if (!bufObj) {
   4368          _mesa_error(ctx, GL_INVALID_OPERATION,
   4369                      "glBindBufferBase(invalid buffer=%u)", buffer);
   4370          return;
   4371       }
   4372    }
   4373 
   4374    /* Note that there's some oddness in the GL 3.1-GL 3.3 specifications with
   4375     * regards to BindBufferBase.  It says (GL 3.1 core spec, page 63):
   4376     *
   4377     *     "BindBufferBase is equivalent to calling BindBufferRange with offset
   4378     *      zero and size equal to the size of buffer."
   4379     *
   4380     * but it says for glGetIntegeri_v (GL 3.1 core spec, page 230):
   4381     *
   4382     *     "If the parameter (starting offset or size) was not specified when the
   4383     *      buffer object was bound, zero is returned."
   4384     *
   4385     * What happens if the size of the buffer changes?  Does the size of the
   4386     * buffer at the moment glBindBufferBase was called still play a role, like
   4387     * the first quote would imply, or is the size meaningless in the
   4388     * glBindBufferBase case like the second quote would suggest?  The GL 4.1
   4389     * core spec page 45 says:
   4390     *
   4391     *     "It is equivalent to calling BindBufferRange with offset zero, while
   4392     *      size is determined by the size of the bound buffer at the time the
   4393     *      binding is used."
   4394     *
   4395     * My interpretation is that the GL 4.1 spec was a clarification of the
   4396     * behavior, not a change.  In particular, this choice will only make
   4397     * rendering work in cases where it would have had undefined results.
   4398     */
   4399 
   4400    switch (target) {
   4401    case GL_TRANSFORM_FEEDBACK_BUFFER:
   4402       _mesa_bind_buffer_base_transform_feedback(ctx,
   4403                                                 ctx->TransformFeedback.CurrentObject,
   4404                                                 index, bufObj, false);
   4405       return;
   4406    case GL_UNIFORM_BUFFER:
   4407       bind_buffer_base_uniform_buffer(ctx, index, bufObj);
   4408       return;
   4409    case GL_SHADER_STORAGE_BUFFER:
   4410       bind_buffer_base_shader_storage_buffer(ctx, index, bufObj);
   4411       return;
   4412    case GL_ATOMIC_COUNTER_BUFFER:
   4413       bind_buffer_base_atomic_buffer(ctx, index, bufObj);
   4414       return;
   4415    default:
   4416       _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
   4417       return;
   4418    }
   4419 }
   4420 
   4421 void GLAPIENTRY
   4422 _mesa_BindBuffersRange(GLenum target, GLuint first, GLsizei count,
   4423                        const GLuint *buffers,
   4424                        const GLintptr *offsets, const GLsizeiptr *sizes)
   4425 {
   4426    GET_CURRENT_CONTEXT(ctx);
   4427 
   4428    if (MESA_VERBOSE & VERBOSE_API) {
   4429       _mesa_debug(ctx, "glBindBuffersRange(%s, %u, %d, %p, %p, %p)\n",
   4430                   _mesa_enum_to_string(target), first, count,
   4431                   buffers, offsets, sizes);
   4432    }
   4433 
   4434    switch (target) {
   4435    case GL_TRANSFORM_FEEDBACK_BUFFER:
   4436       bind_xfb_buffers(ctx, first, count, buffers, true, offsets, sizes,
   4437                        "glBindBuffersRange");
   4438       return;
   4439    case GL_UNIFORM_BUFFER:
   4440       bind_uniform_buffers(ctx, first, count, buffers, true, offsets, sizes,
   4441                            "glBindBuffersRange");
   4442       return;
   4443    case GL_SHADER_STORAGE_BUFFER:
   4444       bind_shader_storage_buffers(ctx, first, count, buffers, true, offsets, sizes,
   4445                                   "glBindBuffersRange");
   4446       return;
   4447    case GL_ATOMIC_COUNTER_BUFFER:
   4448       bind_atomic_buffers(ctx, first, count, buffers, true, offsets, sizes,
   4449                           "glBindBuffersRange");
   4450       return;
   4451    default:
   4452       _mesa_error(ctx, GL_INVALID_ENUM, "glBindBuffersRange(target=%s)",
   4453                   _mesa_enum_to_string(target));
   4454       break;
   4455    }
   4456 }
   4457 
   4458 void GLAPIENTRY
   4459 _mesa_BindBuffersBase(GLenum target, GLuint first, GLsizei count,
   4460                       const GLuint *buffers)
   4461 {
   4462    GET_CURRENT_CONTEXT(ctx);
   4463 
   4464    if (MESA_VERBOSE & VERBOSE_API) {
   4465       _mesa_debug(ctx, "glBindBuffersBase(%s, %u, %d, %p)\n",
   4466                   _mesa_enum_to_string(target), first, count, buffers);
   4467    }
   4468 
   4469    switch (target) {
   4470    case GL_TRANSFORM_FEEDBACK_BUFFER:
   4471       bind_xfb_buffers(ctx, first, count, buffers, false, NULL, NULL,
   4472                        "glBindBuffersBase");
   4473       return;
   4474    case GL_UNIFORM_BUFFER:
   4475       bind_uniform_buffers(ctx, first, count, buffers, false, NULL, NULL,
   4476                            "glBindBuffersBase");
   4477       return;
   4478    case GL_SHADER_STORAGE_BUFFER:
   4479       bind_shader_storage_buffers(ctx, first, count, buffers, false, NULL, NULL,
   4480                                   "glBindBuffersBase");
   4481       return;
   4482    case GL_ATOMIC_COUNTER_BUFFER:
   4483       bind_atomic_buffers(ctx, first, count, buffers, false, NULL, NULL,
   4484                           "glBindBuffersBase");
   4485       return;
   4486    default:
   4487       _mesa_error(ctx, GL_INVALID_ENUM, "glBindBuffersBase(target=%s)",
   4488                   _mesa_enum_to_string(target));
   4489       break;
   4490    }
   4491 }
   4492 
   4493 static ALWAYS_INLINE void
   4494 invalidate_buffer_subdata(struct gl_context *ctx,
   4495                           struct gl_buffer_object *bufObj, GLintptr offset,
   4496                           GLsizeiptr length)
   4497 {
   4498    if (ctx->Driver.InvalidateBufferSubData)
   4499       ctx->Driver.InvalidateBufferSubData(ctx, bufObj, offset, length);
   4500 }
   4501 
   4502 void GLAPIENTRY
   4503 _mesa_InvalidateBufferSubData_no_error(GLuint buffer, GLintptr offset,
   4504                                        GLsizeiptr length)
   4505 {
   4506    GET_CURRENT_CONTEXT(ctx);
   4507 
   4508    struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   4509    invalidate_buffer_subdata(ctx, bufObj, offset, length);
   4510 }
   4511 
   4512 void GLAPIENTRY
   4513 _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset,
   4514                               GLsizeiptr length)
   4515 {
   4516    GET_CURRENT_CONTEXT(ctx);
   4517    struct gl_buffer_object *bufObj;
   4518    const GLintptr end = offset + length;
   4519 
   4520    /* Section 6.5 (Invalidating Buffer Data) of the OpenGL 4.5 (Compatibility
   4521     * Profile) spec says:
   4522     *
   4523     *     "An INVALID_VALUE error is generated if buffer is zero or is not the
   4524     *     name of an existing buffer object."
   4525     */
   4526    bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   4527    if (!bufObj || bufObj == &DummyBufferObject) {
   4528       _mesa_error(ctx, GL_INVALID_VALUE,
   4529                   "glInvalidateBufferSubData(name = %u) invalid object",
   4530                   buffer);
   4531       return;
   4532    }
   4533 
   4534    /* The GL_ARB_invalidate_subdata spec says:
   4535     *
   4536     *     "An INVALID_VALUE error is generated if <offset> or <length> is
   4537     *     negative, or if <offset> + <length> is greater than the value of
   4538     *     BUFFER_SIZE."
   4539     */
   4540    if (offset < 0 || length < 0 || end > bufObj->Size) {
   4541       _mesa_error(ctx, GL_INVALID_VALUE,
   4542                   "glInvalidateBufferSubData(invalid offset or length)");
   4543       return;
   4544    }
   4545 
   4546    /* The OpenGL 4.4 (Core Profile) spec says:
   4547     *
   4548     *     "An INVALID_OPERATION error is generated if buffer is currently
   4549     *     mapped by MapBuffer or if the invalidate range intersects the range
   4550     *     currently mapped by MapBufferRange, unless it was mapped
   4551     *     with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
   4552     */
   4553    if (!(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_PERSISTENT_BIT) &&
   4554        bufferobj_range_mapped(bufObj, offset, length)) {
   4555       _mesa_error(ctx, GL_INVALID_OPERATION,
   4556                   "glInvalidateBufferSubData(intersection with mapped "
   4557                   "range)");
   4558       return;
   4559    }
   4560 
   4561    invalidate_buffer_subdata(ctx, bufObj, offset, length);
   4562 }
   4563 
   4564 void GLAPIENTRY
   4565 _mesa_InvalidateBufferData_no_error(GLuint buffer)
   4566 {
   4567    GET_CURRENT_CONTEXT(ctx);
   4568 
   4569    struct gl_buffer_object *bufObj =_mesa_lookup_bufferobj(ctx, buffer);
   4570    invalidate_buffer_subdata(ctx, bufObj, 0, bufObj->Size);
   4571 }
   4572 
   4573 void GLAPIENTRY
   4574 _mesa_InvalidateBufferData(GLuint buffer)
   4575 {
   4576    GET_CURRENT_CONTEXT(ctx);
   4577    struct gl_buffer_object *bufObj;
   4578 
   4579    /* Section 6.5 (Invalidating Buffer Data) of the OpenGL 4.5 (Compatibility
   4580     * Profile) spec says:
   4581     *
   4582     *     "An INVALID_VALUE error is generated if buffer is zero or is not the
   4583     *     name of an existing buffer object."
   4584     */
   4585    bufObj = _mesa_lookup_bufferobj(ctx, buffer);
   4586    if (!bufObj || bufObj == &DummyBufferObject) {
   4587       _mesa_error(ctx, GL_INVALID_VALUE,
   4588                   "glInvalidateBufferData(name = %u) invalid object",
   4589                   buffer);
   4590       return;
   4591    }
   4592 
   4593    /* The OpenGL 4.4 (Core Profile) spec says:
   4594     *
   4595     *     "An INVALID_OPERATION error is generated if buffer is currently
   4596     *     mapped by MapBuffer or if the invalidate range intersects the range
   4597     *     currently mapped by MapBufferRange, unless it was mapped
   4598     *     with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
   4599     */
   4600    if (_mesa_check_disallowed_mapping(bufObj)) {
   4601       _mesa_error(ctx, GL_INVALID_OPERATION,
   4602                   "glInvalidateBufferData(intersection with mapped "
   4603                   "range)");
   4604       return;
   4605    }
   4606 
   4607    invalidate_buffer_subdata(ctx, bufObj, 0, bufObj->Size);
   4608 }
   4609 
   4610 static void
   4611 buffer_page_commitment(struct gl_context *ctx,
   4612                        struct gl_buffer_object *bufferObj,
   4613                        GLintptr offset, GLsizeiptr size,
   4614                        GLboolean commit, const char *func)
   4615 {
   4616    if (!(bufferObj->StorageFlags & GL_SPARSE_STORAGE_BIT_ARB)) {
   4617       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(not a sparse buffer object)",
   4618                   func);
   4619       return;
   4620    }
   4621 
   4622    if (size < 0 || size > bufferObj->Size ||
   4623        offset < 0 || offset > bufferObj->Size - size) {
   4624       _mesa_error(ctx, GL_INVALID_VALUE, "%s(out of bounds)",
   4625                   func);
   4626       return;
   4627    }
   4628 
   4629    /* The GL_ARB_sparse_buffer extension specification says:
   4630     *
   4631     *     "INVALID_VALUE is generated by BufferPageCommitmentARB if <offset> is
   4632     *     not an integer multiple of SPARSE_BUFFER_PAGE_SIZE_ARB, or if <size>
   4633     *     is not an integer multiple of SPARSE_BUFFER_PAGE_SIZE_ARB and does
   4634     *     not extend to the end of the buffer's data store."
   4635     */
   4636    if (offset % ctx->Const.SparseBufferPageSize != 0) {
   4637       _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset not aligned to page size)",
   4638                   func);
   4639       return;
   4640    }
   4641 
   4642    if (size % ctx->Const.SparseBufferPageSize != 0 &&
   4643        offset + size != bufferObj->Size) {
   4644       _mesa_error(ctx, GL_INVALID_VALUE, "%s(size not aligned to page size)",
   4645                   func);
   4646       return;
   4647    }
   4648 
   4649    ctx->Driver.BufferPageCommitment(ctx, bufferObj, offset, size, commit);
   4650 }
   4651 
   4652 void GLAPIENTRY
   4653 _mesa_BufferPageCommitmentARB(GLenum target, GLintptr offset, GLsizeiptr size,
   4654                               GLboolean commit)
   4655 {
   4656    GET_CURRENT_CONTEXT(ctx);
   4657    struct gl_buffer_object *bufferObj;
   4658 
   4659    bufferObj = get_buffer(ctx, "glBufferPageCommitmentARB", target,
   4660                           GL_INVALID_ENUM);
   4661    if (!bufferObj)
   4662       return;
   4663 
   4664    buffer_page_commitment(ctx, bufferObj, offset, size, commit,
   4665                           "glBufferPageCommitmentARB");
   4666 }
   4667 
   4668 void GLAPIENTRY
   4669 _mesa_NamedBufferPageCommitmentARB(GLuint buffer, GLintptr offset,
   4670                                    GLsizeiptr size, GLboolean commit)
   4671 {
   4672    GET_CURRENT_CONTEXT(ctx);
   4673    struct gl_buffer_object *bufferObj;
   4674 
   4675    bufferObj = _mesa_lookup_bufferobj(ctx, buffer);
   4676    if (!bufferObj || bufferObj == &DummyBufferObject) {
   4677       /* Note: the extension spec is not clear about the excpected error value. */
   4678       _mesa_error(ctx, GL_INVALID_VALUE,
   4679                   "glNamedBufferPageCommitmentARB(name = %u) invalid object",
   4680                   buffer);
   4681       return;
   4682    }
   4683 
   4684    buffer_page_commitment(ctx, bufferObj, offset, size, commit,
   4685                           "glNamedBufferPageCommitmentARB");
   4686 }
   4687