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