2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 * Custom functions for marshalling GL calls from the main thread to a worker
27 * thread when automatic code generation isn't appropriate.
30 #include "main/enums.h"
31 #include "main/macros.h"
36 _mesa_post_marshal_hook(struct gl_context
*ctx
)
38 /* This can be enabled for debugging whether a failure is a synchronization
39 * problem between the main thread and the worker thread, or a failure in
40 * how we actually marshal.
43 _mesa_glthread_finish(ctx
);
46 struct marshal_cmd_Flush
48 struct marshal_cmd_base cmd_base
;
53 _mesa_unmarshal_Flush(struct gl_context
*ctx
,
54 const struct marshal_cmd_Flush
*cmd
)
56 CALL_Flush(ctx
->CurrentServerDispatch
, ());
61 _mesa_marshal_Flush(void)
63 GET_CURRENT_CONTEXT(ctx
);
64 struct marshal_cmd_Flush
*cmd
=
65 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_Flush
,
66 sizeof(struct marshal_cmd_Flush
));
68 _mesa_post_marshal_hook(ctx
);
70 /* Flush() needs to be handled specially. In addition to telling the
71 * background thread to flush, we need to ensure that our own buffer is
72 * submitted to the background thread so that it will complete in a finite
75 _mesa_glthread_flush_batch(ctx
);
78 /* Enable: marshalled asynchronously */
79 struct marshal_cmd_Enable
81 struct marshal_cmd_base cmd_base
;
86 _mesa_unmarshal_Enable(struct gl_context
*ctx
,
87 const struct marshal_cmd_Enable
*cmd
)
89 const GLenum cap
= cmd
->cap
;
90 CALL_Enable(ctx
->CurrentServerDispatch
, (cap
));
94 _mesa_marshal_Enable(GLenum cap
)
96 GET_CURRENT_CONTEXT(ctx
);
97 struct marshal_cmd_Enable
*cmd
;
98 debug_print_marshal("Enable");
100 if (cap
== GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
) {
101 _mesa_glthread_disable(ctx
, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)");
103 cmd
= _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_Enable
,
106 _mesa_post_marshal_hook(ctx
);
110 _mesa_glthread_finish(ctx
);
111 debug_print_sync_fallback("Enable");
112 CALL_Enable(ctx
->CurrentServerDispatch
, (cap
));
115 struct marshal_cmd_ShaderSource
117 struct marshal_cmd_base cmd_base
;
120 /* Followed by GLint length[count], then the contents of all strings,
127 _mesa_unmarshal_ShaderSource(struct gl_context
*ctx
,
128 const struct marshal_cmd_ShaderSource
*cmd
)
130 const GLint
*cmd_length
= (const GLint
*) (cmd
+ 1);
131 const GLchar
*cmd_strings
= (const GLchar
*) (cmd_length
+ cmd
->count
);
132 /* TODO: how to deal with malloc failure? */
133 const GLchar
* *string
= malloc(cmd
->count
* sizeof(const GLchar
*));
136 for (i
= 0; i
< cmd
->count
; ++i
) {
137 string
[i
] = cmd_strings
;
138 cmd_strings
+= cmd_length
[i
];
140 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
141 (cmd
->shader
, cmd
->count
, string
, cmd_length
));
142 free((void *)string
);
147 measure_ShaderSource_strings(GLsizei count
, const GLchar
* const *string
,
148 const GLint
*length_in
, GLint
*length_out
)
151 size_t total_string_length
= 0;
153 for (i
= 0; i
< count
; ++i
) {
154 if (length_in
== NULL
|| length_in
[i
] < 0) {
156 length_out
[i
] = strlen(string
[i
]);
158 length_out
[i
] = length_in
[i
];
160 total_string_length
+= length_out
[i
];
162 return total_string_length
;
167 _mesa_marshal_ShaderSource(GLuint shader
, GLsizei count
,
168 const GLchar
* const *string
, const GLint
*length
)
170 /* TODO: how to report an error if count < 0? */
172 GET_CURRENT_CONTEXT(ctx
);
173 /* TODO: how to deal with malloc failure? */
174 const size_t fixed_cmd_size
= sizeof(struct marshal_cmd_ShaderSource
);
175 STATIC_ASSERT(sizeof(struct marshal_cmd_ShaderSource
) % sizeof(GLint
) == 0);
176 size_t length_size
= count
* sizeof(GLint
);
177 GLint
*length_tmp
= malloc(length_size
);
178 size_t total_string_length
=
179 measure_ShaderSource_strings(count
, string
, length
, length_tmp
);
180 size_t total_cmd_size
= fixed_cmd_size
+ length_size
+ total_string_length
;
182 if (total_cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
183 struct marshal_cmd_ShaderSource
*cmd
=
184 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_ShaderSource
,
186 GLint
*cmd_length
= (GLint
*) (cmd
+ 1);
187 GLchar
*cmd_strings
= (GLchar
*) (cmd_length
+ count
);
190 cmd
->shader
= shader
;
192 memcpy(cmd_length
, length_tmp
, length_size
);
193 for (i
= 0; i
< count
; ++i
) {
194 memcpy(cmd_strings
, string
[i
], cmd_length
[i
]);
195 cmd_strings
+= cmd_length
[i
];
197 _mesa_post_marshal_hook(ctx
);
199 _mesa_glthread_finish(ctx
);
200 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
201 (shader
, count
, string
, length_tmp
));
207 /* BindBufferBase: marshalled asynchronously */
208 struct marshal_cmd_BindBufferBase
210 struct marshal_cmd_base cmd_base
;
216 /** Tracks the current bindings for the vertex array and index array buffers.
218 * This is part of what we need to enable glthread on compat-GL contexts that
219 * happen to use VBOs, without also supporting the full tracking of VBO vs
220 * user vertex array bindings per attribute on each vertex array for
221 * determining what to upload at draw call time.
223 * Note that GL core makes it so that a buffer binding with an invalid handle
224 * in the "buffer" parameter will throw an error, and then a
225 * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
226 * However, in GL core the draw call would throw an error as well, so we don't
227 * really care if our tracking is wrong for this case -- we never need to
228 * marshal user data for draw calls, and the unmarshal will just generate an
229 * error or not as appropriate.
231 * For compatibility GL, we do need to accurately know whether the draw call
232 * on the unmarshal side will dereference a user pointer or load data from a
233 * VBO per vertex. That would make it seem like we need to track whether a
234 * "buffer" is valid, so that we can know when an error will be generated
235 * instead of updating the binding. However, compat GL has the ridiculous
236 * feature that if you pass a bad name, it just gens a buffer object for you,
237 * so we escape without having to know if things are valid or not.
240 track_vbo_binding(struct gl_context
*ctx
, GLenum target
, GLuint buffer
)
242 struct glthread_state
*glthread
= ctx
->GLThread
;
245 case GL_ARRAY_BUFFER
:
246 glthread
->vertex_array_is_vbo
= (buffer
!= 0);
248 case GL_ELEMENT_ARRAY_BUFFER
:
249 /* The current element array buffer binding is actually tracked in the
250 * vertex array object instead of the context, so this would need to
251 * change on vertex array object updates.
253 glthread
->element_array_is_vbo
= (buffer
!= 0);
255 case GL_DRAW_INDIRECT_BUFFER
:
256 glthread
->draw_indirect_buffer_is_vbo
= buffer
!= 0;
262 struct marshal_cmd_BindBuffer
264 struct marshal_cmd_base cmd_base
;
270 * This is just like the code-generated glBindBuffer() support, except that we
271 * call track_vbo_binding().
274 _mesa_unmarshal_BindBuffer(struct gl_context
*ctx
,
275 const struct marshal_cmd_BindBuffer
*cmd
)
277 const GLenum target
= cmd
->target
;
278 const GLuint buffer
= cmd
->buffer
;
279 CALL_BindBuffer(ctx
->CurrentServerDispatch
, (target
, buffer
));
282 _mesa_marshal_BindBuffer(GLenum target
, GLuint buffer
)
284 GET_CURRENT_CONTEXT(ctx
);
285 size_t cmd_size
= sizeof(struct marshal_cmd_BindBuffer
);
286 struct marshal_cmd_BindBuffer
*cmd
;
287 debug_print_marshal("BindBuffer");
289 track_vbo_binding(ctx
, target
, buffer
);
291 if (cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
292 cmd
= _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BindBuffer
,
294 cmd
->target
= target
;
295 cmd
->buffer
= buffer
;
296 _mesa_post_marshal_hook(ctx
);
298 _mesa_glthread_finish(ctx
);
299 CALL_BindBuffer(ctx
->CurrentServerDispatch
, (target
, buffer
));
303 /* BufferData: marshalled asynchronously */
304 struct marshal_cmd_BufferData
306 struct marshal_cmd_base cmd_base
;
310 bool data_null
; /* If set, no data follows for "data" */
311 /* Next size bytes are GLubyte data[size] */
315 _mesa_unmarshal_BufferData(struct gl_context
*ctx
,
316 const struct marshal_cmd_BufferData
*cmd
)
318 const GLenum target
= cmd
->target
;
319 const GLsizeiptr size
= cmd
->size
;
320 const GLenum usage
= cmd
->usage
;
326 data
= (const void *) (cmd
+ 1);
328 CALL_BufferData(ctx
->CurrentServerDispatch
, (target
, size
, data
, usage
));
332 _mesa_marshal_BufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
335 GET_CURRENT_CONTEXT(ctx
);
337 sizeof(struct marshal_cmd_BufferData
) + (data
? size
: 0);
338 debug_print_marshal("BufferData");
340 if (unlikely(size
< 0)) {
341 _mesa_glthread_finish(ctx
);
342 _mesa_error(ctx
, GL_INVALID_VALUE
, "BufferData(size < 0)");
346 if (target
!= GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
&&
347 cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
348 struct marshal_cmd_BufferData
*cmd
=
349 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BufferData
,
352 cmd
->target
= target
;
355 cmd
->data_null
= !data
;
357 char *variable_data
= (char *) (cmd
+ 1);
358 memcpy(variable_data
, data
, size
);
360 _mesa_post_marshal_hook(ctx
);
362 _mesa_glthread_finish(ctx
);
363 CALL_BufferData(ctx
->CurrentServerDispatch
,
364 (target
, size
, data
, usage
));
368 /* BufferSubData: marshalled asynchronously */
369 struct marshal_cmd_BufferSubData
371 struct marshal_cmd_base cmd_base
;
375 /* Next size bytes are GLubyte data[size] */
379 _mesa_unmarshal_BufferSubData(struct gl_context
*ctx
,
380 const struct marshal_cmd_BufferSubData
*cmd
)
382 const GLenum target
= cmd
->target
;
383 const GLintptr offset
= cmd
->offset
;
384 const GLsizeiptr size
= cmd
->size
;
385 const void *data
= (const void *) (cmd
+ 1);
387 CALL_BufferSubData(ctx
->CurrentServerDispatch
,
388 (target
, offset
, size
, data
));
392 _mesa_marshal_BufferSubData(GLenum target
, GLintptr offset
, GLsizeiptr size
,
395 GET_CURRENT_CONTEXT(ctx
);
396 size_t cmd_size
= sizeof(struct marshal_cmd_BufferSubData
) + size
;
398 debug_print_marshal("BufferSubData");
399 if (unlikely(size
< 0)) {
400 _mesa_glthread_finish(ctx
);
401 _mesa_error(ctx
, GL_INVALID_VALUE
, "BufferSubData(size < 0)");
405 if (target
!= GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
&&
406 cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
407 struct marshal_cmd_BufferSubData
*cmd
=
408 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BufferSubData
,
410 cmd
->target
= target
;
411 cmd
->offset
= offset
;
413 char *variable_data
= (char *) (cmd
+ 1);
414 memcpy(variable_data
, data
, size
);
415 _mesa_post_marshal_hook(ctx
);
417 _mesa_glthread_finish(ctx
);
418 CALL_BufferSubData(ctx
->CurrentServerDispatch
,
419 (target
, offset
, size
, data
));
423 /* NamedBufferData: marshalled asynchronously */
424 struct marshal_cmd_NamedBufferData
426 struct marshal_cmd_base cmd_base
;
430 bool data_null
; /* If set, no data follows for "data" */
431 /* Next size bytes are GLubyte data[size] */
435 _mesa_unmarshal_NamedBufferData(struct gl_context
*ctx
,
436 const struct marshal_cmd_NamedBufferData
*cmd
)
438 const GLuint name
= cmd
->name
;
439 const GLsizei size
= cmd
->size
;
440 const GLenum usage
= cmd
->usage
;
446 data
= (const void *) (cmd
+ 1);
448 CALL_NamedBufferData(ctx
->CurrentServerDispatch
,
449 (name
, size
, data
, usage
));
453 _mesa_marshal_NamedBufferData(GLuint buffer
, GLsizeiptr size
,
454 const GLvoid
* data
, GLenum usage
)
456 GET_CURRENT_CONTEXT(ctx
);
457 size_t cmd_size
= sizeof(struct marshal_cmd_NamedBufferData
) + (data
? size
: 0);
459 debug_print_marshal("NamedBufferData");
460 if (unlikely(size
< 0)) {
461 _mesa_glthread_finish(ctx
);
462 _mesa_error(ctx
, GL_INVALID_VALUE
, "NamedBufferData(size < 0)");
466 if (buffer
> 0 && cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
467 struct marshal_cmd_NamedBufferData
*cmd
=
468 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_NamedBufferData
,
473 cmd
->data_null
= !data
;
475 char *variable_data
= (char *) (cmd
+ 1);
476 memcpy(variable_data
, data
, size
);
478 _mesa_post_marshal_hook(ctx
);
480 _mesa_glthread_finish(ctx
);
481 CALL_NamedBufferData(ctx
->CurrentServerDispatch
,
482 (buffer
, size
, data
, usage
));
486 /* NamedBufferSubData: marshalled asynchronously */
487 struct marshal_cmd_NamedBufferSubData
489 struct marshal_cmd_base cmd_base
;
493 /* Next size bytes are GLubyte data[size] */
497 _mesa_unmarshal_NamedBufferSubData(struct gl_context
*ctx
,
498 const struct marshal_cmd_NamedBufferSubData
*cmd
)
500 const GLuint name
= cmd
->name
;
501 const GLintptr offset
= cmd
->offset
;
502 const GLsizei size
= cmd
->size
;
503 const void *data
= (const void *) (cmd
+ 1);
505 CALL_NamedBufferSubData(ctx
->CurrentServerDispatch
,
506 (name
, offset
, size
, data
));
510 _mesa_marshal_NamedBufferSubData(GLuint buffer
, GLintptr offset
,
511 GLsizeiptr size
, const GLvoid
* data
)
513 GET_CURRENT_CONTEXT(ctx
);
514 size_t cmd_size
= sizeof(struct marshal_cmd_NamedBufferSubData
) + size
;
516 debug_print_marshal("NamedBufferSubData");
517 if (unlikely(size
< 0)) {
518 _mesa_glthread_finish(ctx
);
519 _mesa_error(ctx
, GL_INVALID_VALUE
, "NamedBufferSubData(size < 0)");
523 if (buffer
> 0 && cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
524 struct marshal_cmd_NamedBufferSubData
*cmd
=
525 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_NamedBufferSubData
,
528 cmd
->offset
= offset
;
530 char *variable_data
= (char *) (cmd
+ 1);
531 memcpy(variable_data
, data
, size
);
532 _mesa_post_marshal_hook(ctx
);
534 _mesa_glthread_finish(ctx
);
535 CALL_NamedBufferSubData(ctx
->CurrentServerDispatch
,
536 (buffer
, offset
, size
, data
));
540 /* ClearBuffer* (all variants): marshalled asynchronously */
541 struct marshal_cmd_ClearBuffer
543 struct marshal_cmd_base cmd_base
;
549 _mesa_unmarshal_ClearBufferfv(struct gl_context
*ctx
,
550 const struct marshal_cmd_ClearBuffer
*cmd
)
552 const GLenum buffer
= cmd
->buffer
;
553 const GLint drawbuffer
= cmd
->drawbuffer
;
554 const char *variable_data
= (const char *) (cmd
+ 1);
555 const GLfloat
*value
= (const GLfloat
*) variable_data
;
557 CALL_ClearBufferfv(ctx
->CurrentServerDispatch
,
558 (buffer
, drawbuffer
, value
));
562 _mesa_unmarshal_ClearBufferiv(struct gl_context
*ctx
,
563 const struct marshal_cmd_ClearBuffer
*cmd
)
565 const GLenum buffer
= cmd
->buffer
;
566 const GLint drawbuffer
= cmd
->drawbuffer
;
567 const char *variable_data
= (const char *) (cmd
+ 1);
568 const GLint
*value
= (const GLint
*) variable_data
;
570 CALL_ClearBufferiv(ctx
->CurrentServerDispatch
,
571 (buffer
, drawbuffer
, value
));
575 _mesa_unmarshal_ClearBufferuiv(struct gl_context
*ctx
,
576 const struct marshal_cmd_ClearBuffer
*cmd
)
578 const GLenum buffer
= cmd
->buffer
;
579 const GLint drawbuffer
= cmd
->drawbuffer
;
580 const char *variable_data
= (const char *) (cmd
+ 1);
581 const GLuint
*value
= (const GLuint
*) variable_data
;
583 CALL_ClearBufferuiv(ctx
->CurrentServerDispatch
,
584 (buffer
, drawbuffer
, value
));
588 _mesa_unmarshal_ClearBufferfi(struct gl_context
*ctx
,
589 const struct marshal_cmd_ClearBuffer
*cmd
)
591 const GLenum buffer
= cmd
->buffer
;
592 const GLint drawbuffer
= cmd
->drawbuffer
;
593 const char *variable_data
= (const char *) (cmd
+ 1);
594 const GLfloat
*depth
= (const GLfloat
*) variable_data
;
595 const GLint
*stencil
= (const GLint
*) (variable_data
+ 4);
597 CALL_ClearBufferfi(ctx
->CurrentServerDispatch
,
598 (buffer
, drawbuffer
, *depth
, *stencil
));
601 static inline size_t buffer_to_size(GLenum buffer
)
606 case GL_DEPTH_STENCIL
:
616 static inline bool clear_buffer_add_command(struct gl_context
*ctx
, uint16_t id
,
617 GLenum buffer
, GLint drawbuffer
,
618 const GLuint
*value
, size_t size
)
620 size_t cmd_size
= sizeof(struct marshal_cmd_ClearBuffer
) + 4 * size
;
621 if (cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
622 struct marshal_cmd_ClearBuffer
*cmd
=
623 _mesa_glthread_allocate_command(ctx
, id
,
625 cmd
->buffer
= buffer
;
626 cmd
->drawbuffer
= drawbuffer
;
627 GLuint
*variable_data
= (GLuint
*) (cmd
+ 1);
629 COPY_4V(variable_data
, value
);
631 COPY_2V(variable_data
, value
);
633 *variable_data
= *value
;
635 _mesa_post_marshal_hook(ctx
);
643 _mesa_marshal_ClearBufferfv(GLenum buffer
, GLint drawbuffer
,
644 const GLfloat
*value
)
646 GET_CURRENT_CONTEXT(ctx
);
647 debug_print_marshal("ClearBufferfv");
649 if (!(buffer
== GL_DEPTH
|| buffer
== GL_COLOR
)) {
650 _mesa_glthread_finish(ctx
);
652 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
653 * of the OpenGL 4.5 spec states:
655 * "An INVALID_ENUM error is generated by ClearBufferfv and
656 * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
658 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
659 _mesa_enum_to_string(buffer
));
662 size_t size
= buffer_to_size(buffer
);
663 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferfv
, buffer
,
664 drawbuffer
, (GLuint
*)value
, size
)) {
665 debug_print_sync("ClearBufferfv");
666 _mesa_glthread_finish(ctx
);
667 CALL_ClearBufferfv(ctx
->CurrentServerDispatch
,
668 (buffer
, drawbuffer
, value
));
673 _mesa_marshal_ClearBufferiv(GLenum buffer
, GLint drawbuffer
,
676 GET_CURRENT_CONTEXT(ctx
);
677 debug_print_marshal("ClearBufferiv");
679 if (!(buffer
== GL_STENCIL
|| buffer
== GL_COLOR
)) {
680 _mesa_glthread_finish(ctx
);
682 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
683 * of the OpenGL 4.5 spec states:
685 * "An INVALID_ENUM error is generated by ClearBufferiv and
686 * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
688 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
689 _mesa_enum_to_string(buffer
));
692 size_t size
= buffer_to_size(buffer
);
693 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferiv
, buffer
,
694 drawbuffer
, (GLuint
*)value
, size
)) {
695 debug_print_sync("ClearBufferiv");
696 _mesa_glthread_finish(ctx
);
697 CALL_ClearBufferiv(ctx
->CurrentServerDispatch
,
698 (buffer
, drawbuffer
, value
));
703 _mesa_marshal_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
,
706 GET_CURRENT_CONTEXT(ctx
);
707 debug_print_marshal("ClearBufferuiv");
709 if (buffer
!= GL_COLOR
) {
710 _mesa_glthread_finish(ctx
);
712 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
713 * of the OpenGL 4.5 spec states:
715 * "An INVALID_ENUM error is generated by ClearBufferuiv and
716 * ClearNamedFramebufferuiv if buffer is not COLOR."
718 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
719 _mesa_enum_to_string(buffer
));
722 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferuiv
, buffer
,
723 drawbuffer
, (GLuint
*)value
, 4)) {
724 debug_print_sync("ClearBufferuiv");
725 _mesa_glthread_finish(ctx
);
726 CALL_ClearBufferuiv(ctx
->CurrentServerDispatch
,
727 (buffer
, drawbuffer
, value
));
732 _mesa_marshal_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
733 const GLfloat depth
, const GLint stencil
)
735 GET_CURRENT_CONTEXT(ctx
);
736 debug_print_marshal("ClearBufferfi");
738 if (buffer
!= GL_DEPTH_STENCIL
) {
739 _mesa_glthread_finish(ctx
);
741 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
742 * of the OpenGL 4.5 spec states:
744 * "An INVALID_ENUM error is generated by ClearBufferfi and
745 * ClearNamedFramebufferfi if buffer is not DEPTH_STENCIL."
747 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
748 _mesa_enum_to_string(buffer
));
753 value
[1].i
= stencil
;
754 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferfi
, buffer
,
755 drawbuffer
, (GLuint
*)value
, 2)) {
756 debug_print_sync("ClearBufferfi");
757 _mesa_glthread_finish(ctx
);
758 CALL_ClearBufferfi(ctx
->CurrentServerDispatch
,
759 (buffer
, drawbuffer
, depth
, stencil
));