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