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