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