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