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"
35 struct marshal_cmd_Flush
37 struct marshal_cmd_base cmd_base
;
42 _mesa_unmarshal_Flush(struct gl_context
*ctx
,
43 const struct marshal_cmd_Flush
*cmd
)
45 CALL_Flush(ctx
->CurrentServerDispatch
, ());
50 _mesa_marshal_Flush(void)
52 GET_CURRENT_CONTEXT(ctx
);
53 struct marshal_cmd_Flush
*cmd
=
54 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_Flush
,
55 sizeof(struct marshal_cmd_Flush
));
57 _mesa_post_marshal_hook(ctx
);
59 /* Flush() needs to be handled specially. In addition to telling the
60 * background thread to flush, we need to ensure that our own buffer is
61 * submitted to the background thread so that it will complete in a finite
64 _mesa_glthread_flush_batch(ctx
);
67 /* Enable: marshalled asynchronously */
68 struct marshal_cmd_Enable
70 struct marshal_cmd_base cmd_base
;
75 _mesa_unmarshal_Enable(struct gl_context
*ctx
,
76 const struct marshal_cmd_Enable
*cmd
)
78 const GLenum cap
= cmd
->cap
;
79 CALL_Enable(ctx
->CurrentServerDispatch
, (cap
));
83 _mesa_marshal_Enable(GLenum cap
)
85 GET_CURRENT_CONTEXT(ctx
);
86 struct marshal_cmd_Enable
*cmd
;
87 debug_print_marshal("Enable");
89 if (cap
== GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB
) {
90 _mesa_glthread_finish(ctx
);
91 _mesa_glthread_restore_dispatch(ctx
, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)");
93 cmd
= _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_Enable
,
96 _mesa_post_marshal_hook(ctx
);
100 _mesa_glthread_finish(ctx
);
101 debug_print_sync_fallback("Enable");
102 CALL_Enable(ctx
->CurrentServerDispatch
, (cap
));
105 struct marshal_cmd_ShaderSource
107 struct marshal_cmd_base cmd_base
;
110 /* Followed by GLint length[count], then the contents of all strings,
117 _mesa_unmarshal_ShaderSource(struct gl_context
*ctx
,
118 const struct marshal_cmd_ShaderSource
*cmd
)
120 const GLint
*cmd_length
= (const GLint
*) (cmd
+ 1);
121 const GLchar
*cmd_strings
= (const GLchar
*) (cmd_length
+ cmd
->count
);
122 /* TODO: how to deal with malloc failure? */
123 const GLchar
* *string
= malloc(cmd
->count
* sizeof(const GLchar
*));
126 for (i
= 0; i
< cmd
->count
; ++i
) {
127 string
[i
] = cmd_strings
;
128 cmd_strings
+= cmd_length
[i
];
130 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
131 (cmd
->shader
, cmd
->count
, string
, cmd_length
));
132 free((void *)string
);
137 measure_ShaderSource_strings(GLsizei count
, const GLchar
* const *string
,
138 const GLint
*length_in
, GLint
*length_out
)
141 size_t total_string_length
= 0;
143 for (i
= 0; i
< count
; ++i
) {
144 if (length_in
== NULL
|| length_in
[i
] < 0) {
146 length_out
[i
] = strlen(string
[i
]);
148 length_out
[i
] = length_in
[i
];
150 total_string_length
+= length_out
[i
];
152 return total_string_length
;
157 _mesa_marshal_ShaderSource(GLuint shader
, GLsizei count
,
158 const GLchar
* const *string
, const GLint
*length
)
160 /* TODO: how to report an error if count < 0? */
162 GET_CURRENT_CONTEXT(ctx
);
163 /* TODO: how to deal with malloc failure? */
164 const size_t fixed_cmd_size
= sizeof(struct marshal_cmd_ShaderSource
);
165 STATIC_ASSERT(sizeof(struct marshal_cmd_ShaderSource
) % sizeof(GLint
) == 0);
166 size_t length_size
= count
* sizeof(GLint
);
167 GLint
*length_tmp
= malloc(length_size
);
168 size_t total_string_length
=
169 measure_ShaderSource_strings(count
, string
, length
, length_tmp
);
170 size_t total_cmd_size
= fixed_cmd_size
+ length_size
+ total_string_length
;
172 if (total_cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
173 struct marshal_cmd_ShaderSource
*cmd
=
174 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_ShaderSource
,
176 GLint
*cmd_length
= (GLint
*) (cmd
+ 1);
177 GLchar
*cmd_strings
= (GLchar
*) (cmd_length
+ count
);
180 cmd
->shader
= shader
;
182 memcpy(cmd_length
, length_tmp
, length_size
);
183 for (i
= 0; i
< count
; ++i
) {
184 memcpy(cmd_strings
, string
[i
], cmd_length
[i
]);
185 cmd_strings
+= cmd_length
[i
];
187 _mesa_post_marshal_hook(ctx
);
189 _mesa_glthread_finish(ctx
);
190 CALL_ShaderSource(ctx
->CurrentServerDispatch
,
191 (shader
, count
, string
, length_tmp
));
197 /* BindBufferBase: marshalled asynchronously */
198 struct marshal_cmd_BindBufferBase
200 struct marshal_cmd_base cmd_base
;
206 /** Tracks the current bindings for the vertex array and index array buffers.
208 * This is part of what we need to enable glthread on compat-GL contexts that
209 * happen to use VBOs, without also supporting the full tracking of VBO vs
210 * user vertex array bindings per attribute on each vertex array for
211 * determining what to upload at draw call time.
213 * Note that GL core makes it so that a buffer binding with an invalid handle
214 * in the "buffer" parameter will throw an error, and then a
215 * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
216 * However, in GL core the draw call would throw an error as well, so we don't
217 * really care if our tracking is wrong for this case -- we never need to
218 * marshal user data for draw calls, and the unmarshal will just generate an
219 * error or not as appropriate.
221 * For compatibility GL, we do need to accurately know whether the draw call
222 * on the unmarshal side will dereference a user pointer or load data from a
223 * VBO per vertex. That would make it seem like we need to track whether a
224 * "buffer" is valid, so that we can know when an error will be generated
225 * instead of updating the binding. However, compat GL has the ridiculous
226 * feature that if you pass a bad name, it just gens a buffer object for you,
227 * so we escape without having to know if things are valid or not.
230 track_vbo_binding(struct gl_context
*ctx
, GLenum target
, GLuint buffer
)
232 struct glthread_state
*glthread
= ctx
->GLThread
;
235 case GL_ARRAY_BUFFER
:
236 glthread
->vertex_array_is_vbo
= (buffer
!= 0);
238 case GL_ELEMENT_ARRAY_BUFFER
:
239 /* The current element array buffer binding is actually tracked in the
240 * vertex array object instead of the context, so this would need to
241 * change on vertex array object updates.
243 glthread
->element_array_is_vbo
= (buffer
!= 0);
249 struct marshal_cmd_BindBuffer
251 struct marshal_cmd_base cmd_base
;
257 * This is just like the code-generated glBindBuffer() support, except that we
258 * call track_vbo_binding().
261 _mesa_unmarshal_BindBuffer(struct gl_context
*ctx
,
262 const struct marshal_cmd_BindBuffer
*cmd
)
264 const GLenum target
= cmd
->target
;
265 const GLuint buffer
= cmd
->buffer
;
266 CALL_BindBuffer(ctx
->CurrentServerDispatch
, (target
, buffer
));
269 _mesa_marshal_BindBuffer(GLenum target
, GLuint buffer
)
271 GET_CURRENT_CONTEXT(ctx
);
272 size_t cmd_size
= sizeof(struct marshal_cmd_BindBuffer
);
273 struct marshal_cmd_BindBuffer
*cmd
;
274 debug_print_marshal("BindBuffer");
276 track_vbo_binding(ctx
, target
, buffer
);
278 if (cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
279 cmd
= _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BindBuffer
,
281 cmd
->target
= target
;
282 cmd
->buffer
= buffer
;
283 _mesa_post_marshal_hook(ctx
);
285 _mesa_glthread_finish(ctx
);
286 CALL_BindBuffer(ctx
->CurrentServerDispatch
, (target
, buffer
));
290 /* BufferData: marshalled asynchronously */
291 struct marshal_cmd_BufferData
293 struct marshal_cmd_base cmd_base
;
297 bool data_null
; /* If set, no data follows for "data" */
298 /* Next size bytes are GLubyte data[size] */
302 _mesa_unmarshal_BufferData(struct gl_context
*ctx
,
303 const struct marshal_cmd_BufferData
*cmd
)
305 const GLenum target
= cmd
->target
;
306 const GLsizeiptr size
= cmd
->size
;
307 const GLenum usage
= cmd
->usage
;
313 data
= (const void *) (cmd
+ 1);
315 CALL_BufferData(ctx
->CurrentServerDispatch
, (target
, size
, data
, usage
));
319 _mesa_marshal_BufferData(GLenum target
, GLsizeiptr size
, const GLvoid
* data
,
322 GET_CURRENT_CONTEXT(ctx
);
324 sizeof(struct marshal_cmd_BufferData
) + (data
? size
: 0);
325 debug_print_marshal("BufferData");
327 if (unlikely(size
< 0)) {
328 _mesa_glthread_finish(ctx
);
329 _mesa_error(ctx
, GL_INVALID_VALUE
, "BufferData(size < 0)");
333 if (target
!= GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
&&
334 cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
335 struct marshal_cmd_BufferData
*cmd
=
336 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BufferData
,
339 cmd
->target
= target
;
342 cmd
->data_null
= !data
;
344 char *variable_data
= (char *) (cmd
+ 1);
345 memcpy(variable_data
, data
, size
);
347 _mesa_post_marshal_hook(ctx
);
349 _mesa_glthread_finish(ctx
);
350 CALL_BufferData(ctx
->CurrentServerDispatch
,
351 (target
, size
, data
, usage
));
355 /* BufferSubData: marshalled asynchronously */
356 struct marshal_cmd_BufferSubData
358 struct marshal_cmd_base cmd_base
;
362 /* Next size bytes are GLubyte data[size] */
366 _mesa_unmarshal_BufferSubData(struct gl_context
*ctx
,
367 const struct marshal_cmd_BufferSubData
*cmd
)
369 const GLenum target
= cmd
->target
;
370 const GLintptr offset
= cmd
->offset
;
371 const GLsizeiptr size
= cmd
->size
;
372 const void *data
= (const void *) (cmd
+ 1);
374 CALL_BufferSubData(ctx
->CurrentServerDispatch
,
375 (target
, offset
, size
, data
));
379 _mesa_marshal_BufferSubData(GLenum target
, GLintptr offset
, GLsizeiptr size
,
382 GET_CURRENT_CONTEXT(ctx
);
383 size_t cmd_size
= sizeof(struct marshal_cmd_BufferSubData
) + size
;
385 debug_print_marshal("BufferSubData");
386 if (unlikely(size
< 0)) {
387 _mesa_glthread_finish(ctx
);
388 _mesa_error(ctx
, GL_INVALID_VALUE
, "BufferSubData(size < 0)");
392 if (target
!= GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
&&
393 cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
394 struct marshal_cmd_BufferSubData
*cmd
=
395 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_BufferSubData
,
397 cmd
->target
= target
;
398 cmd
->offset
= offset
;
400 char *variable_data
= (char *) (cmd
+ 1);
401 memcpy(variable_data
, data
, size
);
402 _mesa_post_marshal_hook(ctx
);
404 _mesa_glthread_finish(ctx
);
405 CALL_BufferSubData(ctx
->CurrentServerDispatch
,
406 (target
, offset
, size
, data
));
410 /* NamedBufferData: marshalled asynchronously */
411 struct marshal_cmd_NamedBufferData
413 struct marshal_cmd_base cmd_base
;
417 bool data_null
; /* If set, no data follows for "data" */
418 /* Next size bytes are GLubyte data[size] */
422 _mesa_unmarshal_NamedBufferData(struct gl_context
*ctx
,
423 const struct marshal_cmd_NamedBufferData
*cmd
)
425 const GLuint name
= cmd
->name
;
426 const GLsizei size
= cmd
->size
;
427 const GLenum usage
= cmd
->usage
;
433 data
= (const void *) (cmd
+ 1);
435 CALL_NamedBufferData(ctx
->CurrentServerDispatch
,
436 (name
, size
, data
, usage
));
440 _mesa_marshal_NamedBufferData(GLuint buffer
, GLsizeiptr size
,
441 const GLvoid
* data
, GLenum usage
)
443 GET_CURRENT_CONTEXT(ctx
);
444 size_t cmd_size
= sizeof(struct marshal_cmd_NamedBufferData
) + (data
? size
: 0);
446 debug_print_marshal("NamedBufferData");
447 if (unlikely(size
< 0)) {
448 _mesa_glthread_finish(ctx
);
449 _mesa_error(ctx
, GL_INVALID_VALUE
, "NamedBufferData(size < 0)");
453 if (buffer
> 0 && cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
454 struct marshal_cmd_NamedBufferData
*cmd
=
455 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_NamedBufferData
,
460 cmd
->data_null
= !data
;
462 char *variable_data
= (char *) (cmd
+ 1);
463 memcpy(variable_data
, data
, size
);
465 _mesa_post_marshal_hook(ctx
);
467 _mesa_glthread_finish(ctx
);
468 CALL_NamedBufferData(ctx
->CurrentServerDispatch
,
469 (buffer
, size
, data
, usage
));
473 /* NamedBufferSubData: marshalled asynchronously */
474 struct marshal_cmd_NamedBufferSubData
476 struct marshal_cmd_base cmd_base
;
480 /* Next size bytes are GLubyte data[size] */
484 _mesa_unmarshal_NamedBufferSubData(struct gl_context
*ctx
,
485 const struct marshal_cmd_NamedBufferSubData
*cmd
)
487 const GLuint name
= cmd
->name
;
488 const GLintptr offset
= cmd
->offset
;
489 const GLsizei size
= cmd
->size
;
490 const void *data
= (const void *) (cmd
+ 1);
492 CALL_NamedBufferSubData(ctx
->CurrentServerDispatch
,
493 (name
, offset
, size
, data
));
497 _mesa_marshal_NamedBufferSubData(GLuint buffer
, GLintptr offset
,
498 GLsizeiptr size
, const GLvoid
* data
)
500 GET_CURRENT_CONTEXT(ctx
);
501 size_t cmd_size
= sizeof(struct marshal_cmd_NamedBufferSubData
) + size
;
503 debug_print_marshal("NamedBufferSubData");
504 if (unlikely(size
< 0)) {
505 _mesa_glthread_finish(ctx
);
506 _mesa_error(ctx
, GL_INVALID_VALUE
, "NamedBufferSubData(size < 0)");
510 if (buffer
> 0 && cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
511 struct marshal_cmd_NamedBufferSubData
*cmd
=
512 _mesa_glthread_allocate_command(ctx
, DISPATCH_CMD_NamedBufferSubData
,
515 cmd
->offset
= offset
;
517 char *variable_data
= (char *) (cmd
+ 1);
518 memcpy(variable_data
, data
, size
);
519 _mesa_post_marshal_hook(ctx
);
521 _mesa_glthread_finish(ctx
);
522 CALL_NamedBufferSubData(ctx
->CurrentServerDispatch
,
523 (buffer
, offset
, size
, data
));
527 /* ClearBuffer* (all variants): marshalled asynchronously */
528 struct marshal_cmd_ClearBuffer
530 struct marshal_cmd_base cmd_base
;
536 _mesa_unmarshal_ClearBufferfv(struct gl_context
*ctx
,
537 const struct marshal_cmd_ClearBuffer
*cmd
)
539 const GLenum buffer
= cmd
->buffer
;
540 const GLint drawbuffer
= cmd
->drawbuffer
;
541 const char *variable_data
= (const char *) (cmd
+ 1);
542 const GLfloat
*value
= (const GLfloat
*) variable_data
;
544 CALL_ClearBufferfv(ctx
->CurrentServerDispatch
,
545 (buffer
, drawbuffer
, value
));
549 _mesa_unmarshal_ClearBufferiv(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 GLint
*value
= (const GLint
*) variable_data
;
557 CALL_ClearBufferiv(ctx
->CurrentServerDispatch
,
558 (buffer
, drawbuffer
, value
));
562 _mesa_unmarshal_ClearBufferuiv(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 GLuint
*value
= (const GLuint
*) variable_data
;
570 CALL_ClearBufferuiv(ctx
->CurrentServerDispatch
,
571 (buffer
, drawbuffer
, value
));
575 _mesa_unmarshal_ClearBufferfi(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 GLfloat
*depth
= (const GLfloat
*) variable_data
;
582 const GLint
*stencil
= (const GLint
*) (variable_data
+ 4);
584 CALL_ClearBufferfi(ctx
->CurrentServerDispatch
,
585 (buffer
, drawbuffer
, *depth
, *stencil
));
588 static inline size_t buffer_to_size(GLenum buffer
)
593 case GL_DEPTH_STENCIL
:
603 static inline bool clear_buffer_add_command(struct gl_context
*ctx
, uint16_t id
,
604 GLenum buffer
, GLint drawbuffer
,
605 const GLuint
*value
, size_t size
)
607 size_t cmd_size
= sizeof(struct marshal_cmd_ClearBuffer
) + 4 * size
;
608 if (cmd_size
<= MARSHAL_MAX_CMD_SIZE
) {
609 struct marshal_cmd_ClearBuffer
*cmd
=
610 _mesa_glthread_allocate_command(ctx
, id
,
612 cmd
->buffer
= buffer
;
613 cmd
->drawbuffer
= drawbuffer
;
614 GLuint
*variable_data
= (GLuint
*) (cmd
+ 1);
616 COPY_4V(variable_data
, value
);
618 COPY_2V(variable_data
, value
);
620 *variable_data
= *value
;
622 _mesa_post_marshal_hook(ctx
);
630 _mesa_marshal_ClearBufferfv(GLenum buffer
, GLint drawbuffer
,
631 const GLfloat
*value
)
633 GET_CURRENT_CONTEXT(ctx
);
634 debug_print_marshal("ClearBufferfv");
636 if (!(buffer
== GL_DEPTH
|| buffer
== GL_COLOR
)) {
637 _mesa_glthread_finish(ctx
);
639 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
640 * of the OpenGL 4.5 spec states:
642 * "An INVALID_ENUM error is generated by ClearBufferfv and
643 * ClearNamedFramebufferfv if buffer is not COLOR or DEPTH."
645 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfv(buffer=%s)",
646 _mesa_enum_to_string(buffer
));
649 size_t size
= buffer_to_size(buffer
);
650 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferfv
, buffer
,
651 drawbuffer
, (GLuint
*)value
, size
)) {
652 debug_print_sync("ClearBufferfv");
653 _mesa_glthread_finish(ctx
);
654 CALL_ClearBufferfv(ctx
->CurrentServerDispatch
,
655 (buffer
, drawbuffer
, value
));
660 _mesa_marshal_ClearBufferiv(GLenum buffer
, GLint drawbuffer
,
663 GET_CURRENT_CONTEXT(ctx
);
664 debug_print_marshal("ClearBufferiv");
666 if (!(buffer
== GL_STENCIL
|| buffer
== GL_COLOR
)) {
667 _mesa_glthread_finish(ctx
);
669 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
670 * of the OpenGL 4.5 spec states:
672 * "An INVALID_ENUM error is generated by ClearBufferiv and
673 * ClearNamedFramebufferiv if buffer is not COLOR or STENCIL."
675 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferiv(buffer=%s)",
676 _mesa_enum_to_string(buffer
));
679 size_t size
= buffer_to_size(buffer
);
680 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferiv
, buffer
,
681 drawbuffer
, (GLuint
*)value
, size
)) {
682 debug_print_sync("ClearBufferiv");
683 _mesa_glthread_finish(ctx
);
684 CALL_ClearBufferiv(ctx
->CurrentServerDispatch
,
685 (buffer
, drawbuffer
, value
));
690 _mesa_marshal_ClearBufferuiv(GLenum buffer
, GLint drawbuffer
,
693 GET_CURRENT_CONTEXT(ctx
);
694 debug_print_marshal("ClearBufferuiv");
696 if (buffer
!= GL_COLOR
) {
697 _mesa_glthread_finish(ctx
);
699 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
700 * of the OpenGL 4.5 spec states:
702 * "An INVALID_ENUM error is generated by ClearBufferuiv and
703 * ClearNamedFramebufferuiv if buffer is not COLOR."
705 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferuiv(buffer=%s)",
706 _mesa_enum_to_string(buffer
));
709 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferuiv
, buffer
,
710 drawbuffer
, (GLuint
*)value
, 4)) {
711 debug_print_sync("ClearBufferuiv");
712 _mesa_glthread_finish(ctx
);
713 CALL_ClearBufferuiv(ctx
->CurrentServerDispatch
,
714 (buffer
, drawbuffer
, value
));
719 _mesa_marshal_ClearBufferfi(GLenum buffer
, GLint drawbuffer
,
720 const GLfloat depth
, const GLint stencil
)
722 GET_CURRENT_CONTEXT(ctx
);
723 debug_print_marshal("ClearBufferfi");
725 if (buffer
!= GL_DEPTH_STENCIL
) {
726 _mesa_glthread_finish(ctx
);
728 /* Page 498 of the PDF, section '17.4.3.1 Clearing Individual Buffers'
729 * of the OpenGL 4.5 spec states:
731 * "An INVALID_ENUM error is generated by ClearBufferfi and
732 * ClearNamedFramebufferfi if buffer is not DEPTH_STENCIL."
734 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClearBufferfi(buffer=%s)",
735 _mesa_enum_to_string(buffer
));
740 value
[1].i
= stencil
;
741 if (!clear_buffer_add_command(ctx
, DISPATCH_CMD_ClearBufferfi
, buffer
,
742 drawbuffer
, (GLuint
*)value
, 2)) {
743 debug_print_sync("ClearBufferfi");
744 _mesa_glthread_finish(ctx
);
745 CALL_ClearBufferfi(ctx
->CurrentServerDispatch
,
746 (buffer
, drawbuffer
, depth
, stencil
));