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