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"
34 #include "marshal_generated.h"
36 struct marshal_cmd_Flush
38 struct marshal_cmd_base cmd_base
;
43 _mesa_unmarshal_Flush(struct gl_context
*ctx
,
44 const struct marshal_cmd_Flush
*cmd
)
46 CALL_Flush(ctx
->CurrentServerDispatch
, ());
51 _mesa_marshal_Flush(void)
53 GET_CURRENT_CONTEXT(ctx
);
54 struct marshal_cmd_Flush
*cmd
=
55 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_Flush
,
56 sizeof(struct marshal_cmd_Flush
));
58 _mesa_post_marshal_hook(ctx
);
60 /* Flush() needs to be handled specially. In addition to telling the
61 * background thread to flush, we need to ensure that our own buffer is
62 * submitted to the background thread so that it will complete in a finite
65 _mesa_glthread_flush_batch(ctx
);
68 /* Enable: marshalled asynchronously */
69 struct marshal_cmd_Enable
71 struct marshal_cmd_base cmd_base
;
76 _mesa_unmarshal_Enable(struct gl_context
*ctx
,
77 const struct marshal_cmd_Enable
*cmd
)
79 const GLenum cap
= cmd
->cap
;
80 CALL_Enable(ctx
->CurrentServerDispatch
, (cap
));
84 _mesa_marshal_Enable(GLenum cap
)
86 GET_CURRENT_CONTEXT(ctx
);
87 struct marshal_cmd_Enable
*cmd
;
88 debug_print_marshal("Enable");
90 if (cap
== GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
) {
91 _mesa_glthread_finish(ctx
);
92 _mesa_glthread_restore_dispatch(ctx
);
94 cmd
= _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_Enable
,
97 _mesa_post_marshal_hook(ctx
);
101 _mesa_glthread_finish(ctx
);
102 debug_print_sync_fallback("Enable");
103 CALL_Enable(ctx
->CurrentServerDispatch
, (cap
));
106 struct marshal_cmd_ShaderSource
108 struct marshal_cmd_base cmd_base
;
111 /* Followed by GLint length[count], then the contents of all strings,
118 _mesa_unmarshal_ShaderSource(struct gl_context
*ctx
,
119 const struct marshal_cmd_ShaderSource
*cmd
)
121 const GLint
*cmd_length
= (const GLint
*) (cmd
+ 1);
122 const GLchar
*cmd_strings
= (const GLchar
*) (cmd_length
+ cmd
->count
);
123 /* TODO: how to deal with malloc failure? */
124 const GLchar
* *string
= malloc(cmd
->count
* sizeof(const GLchar
*));
127 for (i
= 0; i
< cmd
->count
; ++i
) {
128 string
[i
] = cmd_strings
;
129 cmd_strings
+= cmd_length
[i
];
131 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
132 (cmd
->shader
, cmd
->count
, string
, cmd_length
));
138 measure_ShaderSource_strings(GLsizei count
, const GLchar
* const *string
,
139 const GLint
*length_in
, GLint
*length_out
)
142 size_t total_string_length
= 0;
144 for (i
= 0; i
< count
; ++i
) {
145 if (length_in
== NULL
|| length_in
[i
] < 0) {
147 length_out
[i
] = strlen(string
[i
]);
149 length_out
[i
] = length_in
[i
];
151 total_string_length
+= length_out
[i
];
153 return total_string_length
;
158 _mesa_marshal_ShaderSource(GLuint shader
, GLsizei count
,
159 const GLchar
* const *string
, const GLint
*length
)
161 /* TODO: how to report an error if count < 0? */
163 GET_CURRENT_CONTEXT(ctx
);
164 /* TODO: how to deal with malloc failure? */
165 const size_t fixed_cmd_size
= sizeof(struct marshal_cmd_ShaderSource
);
166 STATIC_ASSERT(sizeof(struct marshal_cmd_ShaderSource
) % sizeof(GLint
) == 0);
167 size_t length_size
= count
* sizeof(GLint
);
168 GLint
*length_tmp
= malloc(length_size
);
169 size_t total_string_length
=
170 measure_ShaderSource_strings(count
, string
, length
, length_tmp
);
171 size_t total_cmd_size
= fixed_cmd_size
+ length_size
+ total_string_length
;
173 if (total_cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
174 struct marshal_cmd_ShaderSource
*cmd
=
175 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_ShaderSource
,
177 GLint
*cmd_length
= (GLint
*) (cmd
+ 1);
178 GLchar
*cmd_strings
= (GLchar
*) (cmd_length
+ count
);
181 cmd
->shader
= shader
;
183 memcpy(cmd_length
, length_tmp
, length_size
);
184 for (i
= 0; i
< count
; ++i
) {
185 memcpy(cmd_strings
, string
[i
], cmd_length
[i
]);
186 cmd_strings
+= cmd_length
[i
];
188 _mesa_post_marshal_hook(ctx
);
190 _mesa_glthread_finish(ctx
);
191 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
192 (shader
, count
, string
, length_tmp
));
198 /* BindBufferBase: marshalled asynchronously */
199 struct marshal_cmd_BindBufferBase
201 struct marshal_cmd_base cmd_base
;
207 /** Tracks the current bindings for the vertex array and index array buffers.
209 * This is part of what we need to enable glthread on compat-GL contexts that
210 * happen to use VBOs, without also supporting the full tracking of VBO vs
211 * user vertex array bindings per attribute on each vertex array for
212 * determining what to upload at draw call time.
214 * Note that GL core makes it so that a buffer binding with an invalid handle
215 * in the "buffer" parameter will throw an error, and then a
216 * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
217 * However, in GL core the draw call would throw an error as well, so we don't
218 * really care if our tracking is wrong for this case -- we never need to
219 * marshal user data for draw calls, and the unmarshal will just generate an
220 * error or not as appropriate.
222 * For compatibility GL, we do need to accurately know whether the draw call
223 * on the unmarshal side will dereference a user pointer or load data from a
224 * VBO per vertex. That would make it seem like we need to track whether a
225 * "buffer" is valid, so that we can know when an error will be generated
226 * instead of updating the binding. However, compat GL has the ridiculous
227 * feature that if you pass a bad name, it just gens a buffer object for you,
228 * so we escape without having to know if things are valid or not.
231 track_vbo_binding(struct gl_context
*ctx
, GLenum target
, GLuint buffer
)
233 struct glthread_state
*glthread
= ctx
->GLThread
;
236 case GL_ARRAY_BUFFER
:
237 glthread
->vertex_array_is_vbo
= (buffer
!= 0);
239 case GL_ELEMENT_ARRAY_BUFFER
:
240 /* The current element array buffer binding is actually tracked in the
241 * vertex array object instead of the context, so this would need to
242 * change on vertex array object updates.
244 glthread
->element_array_is_vbo
= (buffer
!= 0);
250 struct marshal_cmd_BindBuffer
252 struct marshal_cmd_base cmd_base
;
258 * This is just like the code-generated glBindBuffer() support, except that we
259 * call track_vbo_binding().
262 _mesa_unmarshal_BindBuffer(struct gl_context
*ctx
,
263 const struct marshal_cmd_BindBuffer
*cmd
)
265 const GLenum target
= cmd
->target
;
266 const GLuint buffer
= cmd
->buffer
;
267 CALL_BindBuffer(ctx
->CurrentServerDispatch
, (target
, buffer
));
270 _mesa_marshal_BindBuffer(GLenum target
, GLuint buffer
)
272 GET_CURRENT_CONTEXT(ctx
);
273 size_t cmd_size
= sizeof(struct marshal_cmd_BindBuffer
);
274 struct marshal_cmd_BindBuffer
*cmd
;
275 debug_print_marshal("BindBuffer");
277 track_vbo_binding(ctx
, target
, buffer
);
279 if (cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
280 cmd
= _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BindBuffer
,
282 cmd
->target
= target
;
283 cmd
->buffer
= buffer
;
284 _mesa_post_marshal_hook(ctx
);
286 _mesa_glthread_finish(ctx
);
287 CALL_BindBuffer(ctx
->CurrentServerDispatch
, (target
, buffer
));
291 /* BufferData: marshalled asynchronously */
292 struct marshal_cmd_BufferData
294 struct marshal_cmd_base cmd_base
;
298 bool data_null
; /* If set, no data follows for "data" */
299 /* Next size bytes are GLubyte data[size] */
303 _mesa_unmarshal_BufferData(struct gl_context
*ctx
,
304 const struct marshal_cmd_BufferData
*cmd
)
306 const GLenum target
= cmd
->target
;
307 const GLsizeiptr size
= cmd
->size
;
308 const GLenum usage
= cmd
->usage
;
314 data
= (const void *) (cmd
+ 1);
316 CALL_BufferData(ctx
->CurrentServerDispatch
, (target
, size
, data
, usage
));
320 _mesa_marshal_BufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
323 GET_CURRENT_CONTEXT(ctx
);
325 sizeof(struct marshal_cmd_BufferData
) + (data
? size
: 0);
326 debug_print_marshal("BufferData");
328 if (unlikely(size
< 0)) {
329 _mesa_glthread_finish(ctx
);
330 _mesa_error(ctx
, GL_INVALID_VALUE
, "BufferData(size < 0)");
334 if (target
!= GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
&&
335 cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
336 struct marshal_cmd_BufferData
*cmd
=
337 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BufferData
,
340 cmd
->target
= target
;
343 cmd
->data_null
= !data
;
345 char *variable_data
= (char *) (cmd
+ 1);
346 memcpy(variable_data
, data
, size
);
348 _mesa_post_marshal_hook(ctx
);
350 _mesa_glthread_finish(ctx
);
351 CALL_BufferData(ctx
->CurrentServerDispatch
,
352 (target
, size
, data
, usage
));
356 /* BufferSubData: marshalled asynchronously */
357 struct marshal_cmd_BufferSubData
359 struct marshal_cmd_base cmd_base
;
363 /* Next size bytes are GLubyte data[size] */
367 _mesa_unmarshal_BufferSubData(struct gl_context
*ctx
,
368 const struct marshal_cmd_BufferSubData
*cmd
)
370 const GLenum target
= cmd
->target
;
371 const GLintptr offset
= cmd
->offset
;
372 const GLsizeiptr size
= cmd
->size
;
373 const void *data
= (const void *) (cmd
+ 1);
375 CALL_BufferSubData(ctx
->CurrentServerDispatch
,
376 (target
, offset
, size
, data
));
380 _mesa_marshal_BufferSubData(GLenum target
, GLintptr offset
, GLsizeiptr size
,
383 GET_CURRENT_CONTEXT(ctx
);
384 size_t cmd_size
= sizeof(struct marshal_cmd_BufferSubData
) + size
;
386 debug_print_marshal("BufferSubData");
387 if (unlikely(size
< 0)) {
388 _mesa_glthread_finish(ctx
);
389 _mesa_error(ctx
, GL_INVALID_VALUE
, "BufferSubData(size < 0)");
393 if (target
!= GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
&&
394 cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
395 struct marshal_cmd_BufferSubData
*cmd
=
396 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BufferSubData
,
398 cmd
->target
= target
;
399 cmd
->offset
= offset
;
401 char *variable_data
= (char *) (cmd
+ 1);
402 memcpy(variable_data
, data
, size
);
403 _mesa_post_marshal_hook(ctx
);
405 _mesa_glthread_finish(ctx
);
406 CALL_BufferSubData(ctx
->CurrentServerDispatch
,
407 (target
, offset
, size
, data
));
411 /* NamedBufferData: marshalled asynchronously */
412 struct marshal_cmd_NamedBufferData
414 struct marshal_cmd_base cmd_base
;
418 bool data_null
; /* If set, no data follows for "data" */
419 /* Next size bytes are GLubyte data[size] */
423 _mesa_unmarshal_NamedBufferData(struct gl_context
*ctx
,
424 const struct marshal_cmd_NamedBufferData
*cmd
)
426 const GLuint name
= cmd
->name
;
427 const GLsizei size
= cmd
->size
;
428 const GLenum usage
= cmd
->usage
;
434 data
= (const void *) (cmd
+ 1);
436 CALL_NamedBufferData(ctx
->CurrentServerDispatch
,
437 (name
, size
, data
, usage
));
441 _mesa_marshal_NamedBufferData(GLuint buffer
, GLsizeiptr size
,
442 const GLvoid
* data
, GLenum usage
)
444 GET_CURRENT_CONTEXT(ctx
);
445 size_t cmd_size
= sizeof(struct marshal_cmd_NamedBufferData
) + (data
? size
: 0);
447 debug_print_marshal("NamedBufferData");
448 if (unlikely(size
< 0)) {
449 _mesa_glthread_finish(ctx
);
450 _mesa_error(ctx
, GL_INVALID_VALUE
, "NamedBufferData(size < 0)");
454 if (buffer
> 0 && cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
455 struct marshal_cmd_NamedBufferData
*cmd
=
456 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_NamedBufferData
,
461 cmd
->data_null
= !data
;
463 char *variable_data
= (char *) (cmd
+ 1);
464 memcpy(variable_data
, data
, size
);
466 _mesa_post_marshal_hook(ctx
);
468 _mesa_glthread_finish(ctx
);
469 CALL_NamedBufferData(ctx
->CurrentServerDispatch
,
470 (buffer
, size
, data
, usage
));
474 /* NamedBufferSubData: marshalled asynchronously */
475 struct marshal_cmd_NamedBufferSubData
477 struct marshal_cmd_base cmd_base
;
481 /* Next size bytes are GLubyte data[size] */
485 _mesa_unmarshal_NamedBufferSubData(struct gl_context
*ctx
,
486 const struct marshal_cmd_NamedBufferSubData
*cmd
)
488 const GLuint name
= cmd
->name
;
489 const GLintptr offset
= cmd
->offset
;
490 const GLsizei size
= cmd
->size
;
491 const void *data
= (const void *) (cmd
+ 1);
493 CALL_NamedBufferSubData(ctx
->CurrentServerDispatch
,
494 (name
, offset
, size
, data
));
498 _mesa_marshal_NamedBufferSubData(GLuint buffer
, GLintptr offset
,
499 GLsizeiptr size
, const GLvoid
* data
)
501 GET_CURRENT_CONTEXT(ctx
);
502 size_t cmd_size
= sizeof(struct marshal_cmd_NamedBufferSubData
) + size
;
504 debug_print_marshal("NamedBufferSubData");
505 if (unlikely(size
< 0)) {
506 _mesa_glthread_finish(ctx
);
507 _mesa_error(ctx
, GL_INVALID_VALUE
, "NamedBufferSubData(size < 0)");
511 if (buffer
> 0 && cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
512 struct marshal_cmd_NamedBufferSubData
*cmd
=
513 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_NamedBufferSubData
,
516 cmd
->offset
= offset
;
518 char *variable_data
= (char *) (cmd
+ 1);
519 memcpy(variable_data
, data
, size
);
520 _mesa_post_marshal_hook(ctx
);
522 _mesa_glthread_finish(ctx
);
523 CALL_NamedBufferSubData(ctx
->CurrentServerDispatch
,
524 (buffer
, offset
, size
, data
));
528 /* ClearBuffer* (all variants): marshalled asynchronously */
529 struct marshal_cmd_ClearBuffer
531 struct marshal_cmd_base cmd_base
;
537 _mesa_unmarshal_ClearBufferfv(struct gl_context
*ctx
,
538 const struct marshal_cmd_ClearBuffer
*cmd
)
540 const GLenum buffer
= cmd
->buffer
;
541 const GLint drawbuffer
= cmd
->drawbuffer
;
542 const char *variable_data
= (const char *) (cmd
+ 1);
543 const GLfloat
*value
= (const GLfloat
*) variable_data
;
545 CALL_ClearBufferfv(ctx
->CurrentServerDispatch
,
546 (buffer
, drawbuffer
, value
));
550 _mesa_unmarshal_ClearBufferiv(struct gl_context
*ctx
,
551 const struct marshal_cmd_ClearBuffer
*cmd
)
553 const GLenum buffer
= cmd
->buffer
;
554 const GLint drawbuffer
= cmd
->drawbuffer
;
555 const char *variable_data
= (const char *) (cmd
+ 1);
556 const GLint
*value
= (const GLint
*) variable_data
;
558 CALL_ClearBufferiv(ctx
->CurrentServerDispatch
,
559 (buffer
, drawbuffer
, value
));
563 _mesa_unmarshal_ClearBufferuiv(struct gl_context
*ctx
,
564 const struct marshal_cmd_ClearBuffer
*cmd
)
566 const GLenum buffer
= cmd
->buffer
;
567 const GLint drawbuffer
= cmd
->drawbuffer
;
568 const char *variable_data
= (const char *) (cmd
+ 1);
569 const GLuint
*value
= (const GLuint
*) variable_data
;
571 CALL_ClearBufferuiv(ctx
->CurrentServerDispatch
,
572 (buffer
, drawbuffer
, value
));
576 _mesa_unmarshal_ClearBufferfi(struct gl_context
*ctx
,
577 const struct marshal_cmd_ClearBuffer
*cmd
)
579 const GLenum buffer
= cmd
->buffer
;
580 const GLint drawbuffer
= cmd
->drawbuffer
;
581 const char *variable_data
= (const char *) (cmd
+ 1);
582 const GLfloat
*depth
= (const GLfloat
*) variable_data
;
583 const GLint
*stencil
= (const GLint
*) (variable_data
+ 4);
585 CALL_ClearBufferfi(ctx
->CurrentServerDispatch
,
586 (buffer
, drawbuffer
, *depth
, *stencil
));
589 static inline size_t buffer_to_size(GLenum buffer
)
594 case GL_DEPTH_STENCIL
:
604 static inline bool clear_buffer_add_command(struct gl_context
*ctx
, uint16_t id
,
605 GLenum buffer
, GLint drawbuffer
,
606 const GLuint
*value
, size_t size
)
608 size_t cmd_size
= sizeof(struct marshal_cmd_ClearBuffer
) + 4 * size
;
609 if (cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
610 struct marshal_cmd_ClearBuffer
*cmd
=
611 _mesa_glthread_allocate_command(ctx
, id
,
613 cmd
->buffer
= buffer
;
614 cmd
->drawbuffer
= drawbuffer
;
615 GLuint
*variable_data
= (GLuint
*) (cmd
+ 1);
617 COPY_4V(variable_data
, value
);
619 COPY_2V(variable_data
, value
);
621 *variable_data
= *value
;
623 _mesa_post_marshal_hook(ctx
);
631 _mesa_marshal_ClearBufferfv(GLenum buffer
, GLint drawbuffer
,
632 const GLfloat
*value
)
634 GET_CURRENT_CONTEXT(ctx
);
635 debug_print_marshal("ClearBufferfv");
637 if (!(buffer
== GL_DEPTH
|| buffer
== GL_COLOR
)) {
638 _mesa_glthread_finish(ctx
);
640 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
641 * of the OpenGL 4.5 spec states:
643 * "An INVALID_ENUM error is generated by ClearBufferfv and
644 * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
646 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
647 _mesa_enum_to_string(buffer
));
650 size_t size
= buffer_to_size(buffer
);
651 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferfv
, buffer
,
652 drawbuffer
, (GLuint
*)value
, size
)) {
653 debug_print_sync("ClearBufferfv");
654 _mesa_glthread_finish(ctx
);
655 CALL_ClearBufferfv(ctx
->CurrentServerDispatch
,
656 (buffer
, drawbuffer
, value
));
661 _mesa_marshal_ClearBufferiv(GLenum buffer
, GLint drawbuffer
,
664 GET_CURRENT_CONTEXT(ctx
);
665 debug_print_marshal("ClearBufferiv");
667 if (!(buffer
== GL_STENCIL
|| buffer
== GL_COLOR
)) {
668 _mesa_glthread_finish(ctx
);
670 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
671 * of the OpenGL 4.5 spec states:
673 * "An INVALID_ENUM error is generated by ClearBufferiv and
674 * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
676 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
677 _mesa_enum_to_string(buffer
));
680 size_t size
= buffer_to_size(buffer
);
681 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferiv
, buffer
,
682 drawbuffer
, (GLuint
*)value
, size
)) {
683 debug_print_sync("ClearBufferiv");
684 _mesa_glthread_finish(ctx
);
685 CALL_ClearBufferiv(ctx
->CurrentServerDispatch
,
686 (buffer
, drawbuffer
, value
));
691 _mesa_marshal_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
,
694 GET_CURRENT_CONTEXT(ctx
);
695 debug_print_marshal("ClearBufferuiv");
697 if (buffer
!= GL_COLOR
) {
698 _mesa_glthread_finish(ctx
);
700 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
701 * of the OpenGL 4.5 spec states:
703 * "An INVALID_ENUM error is generated by ClearBufferuiv and
704 * ClearNamedFramebufferuiv if buffer is not COLOR."
706 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
707 _mesa_enum_to_string(buffer
));
710 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferuiv
, buffer
,
711 drawbuffer
, (GLuint
*)value
, 4)) {
712 debug_print_sync("ClearBufferuiv");
713 _mesa_glthread_finish(ctx
);
714 CALL_ClearBufferuiv(ctx
->CurrentServerDispatch
,
715 (buffer
, drawbuffer
, value
));
720 _mesa_marshal_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
721 const GLfloat depth
, const GLint stencil
)
723 GET_CURRENT_CONTEXT(ctx
);
724 debug_print_marshal("ClearBufferfi");
726 if (buffer
!= GL_DEPTH_STENCIL
) {
727 _mesa_glthread_finish(ctx
);
729 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
730 * of the OpenGL 4.5 spec states:
732 * "An INVALID_ENUM error is generated by ClearBufferfi and
733 * ClearNamedFramebufferfi if buffer is not DEPTH_STENCIL."
735 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
736 _mesa_enum_to_string(buffer
));
741 value
[1].i
= stencil
;
742 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferfi
, buffer
,
743 drawbuffer
, (GLuint
*)value
, 2)) {
744 debug_print_sync("ClearBufferfi");
745 _mesa_glthread_finish(ctx
);
746 CALL_ClearBufferfi(ctx
->CurrentServerDispatch
,
747 (buffer
, drawbuffer
, depth
, stencil
));