2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
27 #include "api_validate.h"
29 #include "bufferobj.h"
33 #include "pipelineobj.h"
36 #include "transformfeedback.h"
39 #include "program/prog_print.h"
43 check_blend_func_error(struct gl_context
*ctx
)
45 /* The ARB_blend_func_extended spec's ERRORS section says:
47 * "The error INVALID_OPERATION is generated by Begin or any procedure
48 * that implicitly calls Begin if any draw buffer has a blend function
49 * requiring the second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR,
50 * SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that
51 * has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active
52 * color attachements."
54 for (unsigned i
= ctx
->Const
.MaxDualSourceDrawBuffers
;
55 i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
;
57 if (ctx
->Color
.Blend
[i
]._UsesDualSrc
) {
58 _mesa_error(ctx
, GL_INVALID_OPERATION
,
59 "dual source blend on illegal attachment");
64 if (ctx
->Color
.BlendEnabled
&& ctx
->Color
._AdvancedBlendMode
) {
65 /* The KHR_blend_equation_advanced spec says:
67 * "If any non-NONE draw buffer uses a blend equation found in table
68 * X.1 or X.2, the error INVALID_OPERATION is generated by Begin or
69 * any operation that implicitly calls Begin (such as DrawElements)
72 * * the draw buffer for color output zero selects multiple color
73 * buffers (e.g., FRONT_AND_BACK in the default framebuffer); or
75 * * the draw buffer for any other color output is not NONE."
77 if (ctx
->DrawBuffer
->ColorDrawBuffer
[0] == GL_FRONT_AND_BACK
) {
78 _mesa_error(ctx
, GL_INVALID_OPERATION
,
79 "advanced blending is active and draw buffer for color "
80 "output zero selects multiple color buffers");
84 for (unsigned i
= 1; i
< ctx
->DrawBuffer
->_NumColorDrawBuffers
; i
++) {
85 if (ctx
->DrawBuffer
->ColorDrawBuffer
[i
] != GL_NONE
) {
86 _mesa_error(ctx
, GL_INVALID_OPERATION
,
87 "advanced blending is active with multiple color "
93 /* The KHR_blend_equation_advanced spec says:
95 * "Advanced blending equations require the use of a fragment shader
96 * with a matching "blend_support" layout qualifier. If the current
97 * blend equation is found in table X.1 or X.2, and the active
98 * fragment shader does not include the layout qualifier matching
99 * the blend equation or "blend_support_all_equations", the error
100 * INVALID_OPERATION is generated [...]"
102 const struct gl_program
*prog
= ctx
->_Shader
->_CurrentFragmentProgram
;
103 const GLbitfield blend_support
= !prog
? 0 : prog
->sh
.fs
.BlendSupport
;
105 if ((blend_support
& ctx
->Color
._AdvancedBlendMode
) == 0) {
106 _mesa_error(ctx
, GL_INVALID_OPERATION
,
107 "fragment shader does not allow advanced blending mode "
109 _mesa_enum_to_string(ctx
->Color
.Blend
[0].EquationRGB
));
118 * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
119 * is called to see if it's valid to render. This involves checking that
120 * the current shader is valid and the framebuffer is complete.
121 * It also check the current pipeline object is valid if any.
122 * If an error is detected it'll be recorded here.
123 * \return GL_TRUE if OK to render, GL_FALSE if not
126 _mesa_valid_to_render(struct gl_context
*ctx
, const char *where
)
128 /* This depends on having up to date derived state (shaders) */
130 _mesa_update_state(ctx
);
132 if (ctx
->API
== API_OPENGL_COMPAT
) {
133 /* Any shader stages that are not supplied by the GLSL shader and have
134 * assembly shaders enabled must now be validated.
136 if (!ctx
->_Shader
->CurrentProgram
[MESA_SHADER_VERTEX
]
137 && ctx
->VertexProgram
.Enabled
&& !ctx
->VertexProgram
._Enabled
) {
138 _mesa_error(ctx
, GL_INVALID_OPERATION
,
139 "%s(vertex program not valid)", where
);
143 if (!ctx
->_Shader
->CurrentProgram
[MESA_SHADER_FRAGMENT
]) {
144 if (ctx
->FragmentProgram
.Enabled
&& !ctx
->FragmentProgram
._Enabled
) {
145 _mesa_error(ctx
, GL_INVALID_OPERATION
,
146 "%s(fragment program not valid)", where
);
150 /* If drawing to integer-valued color buffers, there must be an
151 * active fragment shader (GL_EXT_texture_integer).
153 if (ctx
->DrawBuffer
&& ctx
->DrawBuffer
->_IntegerBuffers
) {
154 _mesa_error(ctx
, GL_INVALID_OPERATION
,
155 "%s(integer format but no fragment shader)", where
);
161 /* A pipeline object is bound */
162 if (ctx
->_Shader
->Name
&& !ctx
->_Shader
->Validated
) {
163 if (!_mesa_validate_program_pipeline(ctx
, ctx
->_Shader
)) {
164 _mesa_error(ctx
, GL_INVALID_OPERATION
,
165 "glValidateProgramPipeline failed to validate the "
171 /* If a program is active and SSO not in use, check if validation of
172 * samplers succeeded for the active program. */
173 if (ctx
->_Shader
->ActiveProgram
&& ctx
->_Shader
!= ctx
->Pipeline
.Current
) {
175 if (!_mesa_sampler_uniforms_are_valid(ctx
->_Shader
->ActiveProgram
,
177 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", errMsg
);
182 if (ctx
->DrawBuffer
->_Status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
183 _mesa_error(ctx
, GL_INVALID_FRAMEBUFFER_OPERATION_EXT
,
184 "%s(incomplete framebuffer)", where
);
188 if (!check_blend_func_error(ctx
)) {
193 if (ctx
->_Shader
->Flags
& GLSL_LOG
) {
194 struct gl_program
**prog
= ctx
->_Shader
->CurrentProgram
;
196 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
197 if (prog
[i
] == NULL
|| prog
[i
]->_Used
)
200 /* This is the first time this shader is being used.
201 * Append shader's constants/uniforms to log file.
203 * Only log data for the program target that matches the shader
204 * target. It's possible to have a program bound to the vertex
205 * shader target that also supplied a fragment shader. If that
206 * program isn't also bound to the fragment shader target we don't
207 * want to log its fragment data.
209 _mesa_append_uniforms_to_file(prog
[i
]);
212 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
214 prog
[i
]->_Used
= GL_TRUE
;
224 * Check if OK to draw arrays/elements.
227 check_valid_to_render(struct gl_context
*ctx
, const char *function
)
229 if (!_mesa_valid_to_render(ctx
, function
)) {
233 if (!_mesa_all_buffers_are_unmapped(ctx
->Array
.VAO
)) {
234 _mesa_error(ctx
, GL_INVALID_OPERATION
,
235 "%s(vertex buffers are mapped)", function
);
239 /* Section 11.2 (Tessellation) of the ES 3.2 spec says:
241 * "An INVALID_OPERATION error is generated by any command that
242 * transfers vertices to the GL if the current program state has
243 * one but not both of a tessellation control shader and tessellation
244 * evaluation shader."
246 * The OpenGL spec argues that this is allowed because a tess ctrl shader
247 * without a tess eval shader can be used with transform feedback.
248 * However, glBeginTransformFeedback doesn't allow GL_PATCHES and
249 * therefore doesn't allow tessellation.
251 * Further investigation showed that this is indeed a spec bug and
252 * a tess ctrl shader without a tess eval shader shouldn't have been
253 * allowed, because there is no API in GL 4.0 that can make use this
254 * to produce something useful.
256 * Also, all vendors except one don't support a tess ctrl shader without
257 * a tess eval shader anyway.
259 if (ctx
->TessCtrlProgram
._Current
&& !ctx
->TessEvalProgram
._Current
) {
260 _mesa_error(ctx
, GL_INVALID_OPERATION
,
261 "%s(tess eval shader is missing)", function
);
267 /* Section 11.2 (Tessellation) of the ES 3.2 spec says:
269 * "An INVALID_OPERATION error is generated by any command that
270 * transfers vertices to the GL if the current program state has
271 * one but not both of a tessellation control shader and tessellation
272 * evaluation shader."
274 if (_mesa_is_gles3(ctx
) &&
275 ctx
->TessEvalProgram
._Current
&& !ctx
->TessCtrlProgram
._Current
) {
276 _mesa_error(ctx
, GL_INVALID_OPERATION
,
277 "%s(tess ctrl shader is missing)", function
);
281 /* For ES2, we can draw if we have a vertex program/shader). */
282 return ctx
->VertexProgram
._Current
!= NULL
;
285 /* For OpenGL ES, only draw if we have vertex positions
287 if (!ctx
->Array
.VAO
->VertexAttrib
[VERT_ATTRIB_POS
].Enabled
)
291 case API_OPENGL_CORE
:
292 /* Section 10.4 (Drawing Commands Using Vertex Arrays) of the OpenGL 4.5
293 * Core Profile spec says:
295 * "An INVALID_OPERATION error is generated if no vertex array
296 * object is bound (see section 10.3.1)."
298 if (ctx
->Array
.VAO
== ctx
->Array
.DefaultVAO
) {
299 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s(no VAO bound)", function
);
303 /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec
306 * "If there is no active program for the vertex or fragment shader
307 * stages, the results of vertex and/or fragment processing will be
308 * undefined. However, this is not an error."
310 * The fragment shader is not tested here because other state (e.g.,
311 * GL_RASTERIZER_DISCARD) affects whether or not we actually care.
313 return ctx
->VertexProgram
._Current
!= NULL
;
315 case API_OPENGL_COMPAT
:
316 if (ctx
->VertexProgram
._Current
!= NULL
) {
317 /* Draw regardless of whether or not we have any vertex arrays.
318 * (Ex: could draw a point using a constant vertex pos)
322 /* Draw if we have vertex positions (GL_VERTEX_ARRAY or generic
325 return (ctx
->Array
.VAO
->VertexAttrib
[VERT_ATTRIB_POS
].Enabled
||
326 ctx
->Array
.VAO
->VertexAttrib
[VERT_ATTRIB_GENERIC0
].Enabled
);
331 unreachable("Invalid API value in check_valid_to_render()");
339 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
340 * etc? The set of legal values depends on whether geometry shaders/programs
342 * Note: This may be called during display list compilation.
345 _mesa_is_valid_prim_mode(struct gl_context
*ctx
, GLenum mode
)
347 /* The overwhelmingly common case is (mode <= GL_TRIANGLE_FAN). Test that
348 * first and exit. You would think that a switch-statement would be the
349 * right approach, but at least GCC 4.7.2 generates some pretty dire code
350 * for the common case.
352 if (likely(mode
<= GL_TRIANGLE_FAN
))
355 if (mode
<= GL_POLYGON
)
356 return (ctx
->API
== API_OPENGL_COMPAT
);
358 if (mode
<= GL_TRIANGLE_STRIP_ADJACENCY
)
359 return _mesa_has_geometry_shaders(ctx
);
361 if (mode
== GL_PATCHES
)
362 return _mesa_has_tessellation(ctx
);
369 * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(),
370 * etc? Also, do additional checking related to transformation feedback.
371 * Note: this function cannot be called during glNewList(GL_COMPILE) because
372 * this code depends on current transform feedback state.
373 * Also, do additional checking related to tessellation shaders.
376 _mesa_valid_prim_mode(struct gl_context
*ctx
, GLenum mode
, const char *name
)
378 bool valid_enum
= _mesa_is_valid_prim_mode(ctx
, mode
);
381 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(mode=%x)", name
, mode
);
385 /* From the OpenGL 4.5 specification, section 11.3.1:
387 * The error INVALID_OPERATION is generated if Begin, or any command that
388 * implicitly calls Begin, is called when a geometry shader is active and:
390 * * the input primitive type of the current geometry shader is
391 * POINTS and <mode> is not POINTS,
393 * * the input primitive type of the current geometry shader is
394 * LINES and <mode> is not LINES, LINE_STRIP, or LINE_LOOP,
396 * * the input primitive type of the current geometry shader is
397 * TRIANGLES and <mode> is not TRIANGLES, TRIANGLE_STRIP or
400 * * the input primitive type of the current geometry shader is
401 * LINES_ADJACENCY_ARB and <mode> is not LINES_ADJACENCY_ARB or
402 * LINE_STRIP_ADJACENCY_ARB, or
404 * * the input primitive type of the current geometry shader is
405 * TRIANGLES_ADJACENCY_ARB and <mode> is not
406 * TRIANGLES_ADJACENCY_ARB or TRIANGLE_STRIP_ADJACENCY_ARB.
408 * The GL spec doesn't mention any interaction with tessellation, which
409 * is clearly a spec bug. The same rule should apply, but instead of
410 * the draw primitive mode, the tessellation evaluation shader primitive
411 * mode should be used for the checking.
413 if (ctx
->_Shader
->CurrentProgram
[MESA_SHADER_GEOMETRY
]) {
414 const GLenum geom_mode
=
415 ctx
->_Shader
->CurrentProgram
[MESA_SHADER_GEOMETRY
]->
416 info
.gs
.input_primitive
;
417 struct gl_program
*tes
=
418 ctx
->_Shader
->CurrentProgram
[MESA_SHADER_TESS_EVAL
];
419 GLenum mode_before_gs
= mode
;
422 if (tes
->info
.tess
.point_mode
)
423 mode_before_gs
= GL_POINTS
;
424 else if (tes
->info
.tess
.primitive_mode
== GL_ISOLINES
)
425 mode_before_gs
= GL_LINES
;
427 /* the GL_QUADS mode generates triangles too */
428 mode_before_gs
= GL_TRIANGLES
;
431 switch (mode_before_gs
) {
433 valid_enum
= (geom_mode
== GL_POINTS
);
438 valid_enum
= (geom_mode
== GL_LINES
);
441 case GL_TRIANGLE_STRIP
:
442 case GL_TRIANGLE_FAN
:
443 valid_enum
= (geom_mode
== GL_TRIANGLES
);
450 case GL_LINES_ADJACENCY
:
451 case GL_LINE_STRIP_ADJACENCY
:
452 valid_enum
= (geom_mode
== GL_LINES_ADJACENCY
);
454 case GL_TRIANGLES_ADJACENCY
:
455 case GL_TRIANGLE_STRIP_ADJACENCY
:
456 valid_enum
= (geom_mode
== GL_TRIANGLES_ADJACENCY
);
463 _mesa_error(ctx
, GL_INVALID_OPERATION
,
464 "%s(mode=%s vs geometry shader input %s)",
466 _mesa_lookup_prim_by_nr(mode_before_gs
),
467 _mesa_lookup_prim_by_nr(geom_mode
));
472 /* From the OpenGL 4.0 (Core Profile) spec (section 2.12):
474 * "Tessellation operates only on patch primitives. If tessellation is
475 * active, any command that transfers vertices to the GL will
476 * generate an INVALID_OPERATION error if the primitive mode is not
478 * Patch primitives are not supported by pipeline stages below the
479 * tessellation evaluation shader. If there is no active program
480 * object or the active program object does not contain a tessellation
481 * evaluation shader, the error INVALID_OPERATION is generated by any
482 * command that transfers vertices to the GL if the primitive mode is
486 if (ctx
->_Shader
->CurrentProgram
[MESA_SHADER_TESS_EVAL
] ||
487 ctx
->_Shader
->CurrentProgram
[MESA_SHADER_TESS_CTRL
]) {
488 if (mode
!= GL_PATCHES
) {
489 _mesa_error(ctx
, GL_INVALID_OPERATION
,
490 "only GL_PATCHES valid with tessellation");
495 if (mode
== GL_PATCHES
) {
496 _mesa_error(ctx
, GL_INVALID_OPERATION
,
497 "GL_PATCHES only valid with tessellation");
502 /* From the GL_EXT_transform_feedback spec:
504 * "The error INVALID_OPERATION is generated if Begin, or any command
505 * that performs an explicit Begin, is called when:
507 * * a geometry shader is not active and <mode> does not match the
508 * allowed begin modes for the current transform feedback state as
509 * given by table X.1.
511 * * a geometry shader is active and the output primitive type of the
512 * geometry shader does not match the allowed begin modes for the
513 * current transform feedback state as given by table X.1.
516 if (_mesa_is_xfb_active_and_unpaused(ctx
)) {
517 GLboolean pass
= GL_TRUE
;
519 if(ctx
->_Shader
->CurrentProgram
[MESA_SHADER_GEOMETRY
]) {
520 switch (ctx
->_Shader
->CurrentProgram
[MESA_SHADER_GEOMETRY
]->
521 info
.gs
.output_primitive
) {
523 pass
= ctx
->TransformFeedback
.Mode
== GL_POINTS
;
526 pass
= ctx
->TransformFeedback
.Mode
== GL_LINES
;
528 case GL_TRIANGLE_STRIP
:
529 pass
= ctx
->TransformFeedback
.Mode
== GL_TRIANGLES
;
535 else if (ctx
->_Shader
->CurrentProgram
[MESA_SHADER_TESS_EVAL
]) {
536 struct gl_program
*tes
=
537 ctx
->_Shader
->CurrentProgram
[MESA_SHADER_TESS_EVAL
];
538 if (tes
->info
.tess
.point_mode
)
539 pass
= ctx
->TransformFeedback
.Mode
== GL_POINTS
;
540 else if (tes
->info
.tess
.primitive_mode
== GL_ISOLINES
)
541 pass
= ctx
->TransformFeedback
.Mode
== GL_LINES
;
543 pass
= ctx
->TransformFeedback
.Mode
== GL_TRIANGLES
;
548 pass
= ctx
->TransformFeedback
.Mode
== GL_POINTS
;
553 pass
= ctx
->TransformFeedback
.Mode
== GL_LINES
;
556 pass
= ctx
->TransformFeedback
.Mode
== GL_TRIANGLES
;
561 _mesa_error(ctx
, GL_INVALID_OPERATION
,
562 "%s(mode=%s vs transform feedback %s)",
564 _mesa_lookup_prim_by_nr(mode
),
565 _mesa_lookup_prim_by_nr(ctx
->TransformFeedback
.Mode
));
570 /* From GL_INTEL_conservative_rasterization spec:
572 * The conservative rasterization option applies only to polygons with
573 * PolygonMode state set to FILL. Draw requests for polygons with different
574 * PolygonMode setting or for other primitive types (points/lines) generate
575 * INVALID_OPERATION error.
577 if (ctx
->IntelConservativeRasterization
) {
578 GLboolean pass
= GL_TRUE
;
585 case GL_LINES_ADJACENCY
:
586 case GL_LINE_STRIP_ADJACENCY
:
590 case GL_TRIANGLE_STRIP
:
591 case GL_TRIANGLE_FAN
:
595 case GL_TRIANGLES_ADJACENCY
:
596 case GL_TRIANGLE_STRIP_ADJACENCY
:
597 if (ctx
->Polygon
.FrontMode
!= GL_FILL
||
598 ctx
->Polygon
.BackMode
!= GL_FILL
)
605 _mesa_error(ctx
, GL_INVALID_OPERATION
,
606 "mode=%s invalid with GL_INTEL_conservative_rasterization",
607 _mesa_lookup_prim_by_nr(mode
));
616 * Verify that the element type is valid.
618 * Generates \c GL_INVALID_ENUM and returns \c false if it is not.
621 valid_elements_type(struct gl_context
*ctx
, GLenum type
, const char *name
)
624 case GL_UNSIGNED_BYTE
:
625 case GL_UNSIGNED_SHORT
:
626 case GL_UNSIGNED_INT
:
630 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(type = %s)", name
,
631 _mesa_enum_to_string(type
));
637 validate_DrawElements_common(struct gl_context
*ctx
,
638 GLenum mode
, GLsizei count
, GLenum type
,
639 const GLvoid
*indices
,
642 /* Section 2.14.2 (Transform Feedback Primitive Capture) of the OpenGL ES
645 * The error INVALID_OPERATION is also generated by DrawElements,
646 * DrawElementsInstanced, and DrawRangeElements while transform feedback
647 * is active and not paused, regardless of mode.
649 * The OES_geometry_shader_spec says:
655 * (13) Does this extension change how transform feedback operates
656 * compared to unextended OpenGL ES 3.0 or 3.1?
658 * RESOLVED: Yes... Since we no longer require being able to predict how
659 * much geometry will be generated, we also lift the restriction that
660 * only DrawArray* commands are supported and also support the
661 * DrawElements* commands for transform feedback.
663 * This should also be reflected in the body of the spec, but that appears
664 * to have been overlooked. The body of the spec only explicitly allows
665 * the indirect versions.
667 if (_mesa_is_gles3(ctx
) &&
668 !_mesa_has_OES_geometry_shader(ctx
) &&
669 _mesa_is_xfb_active_and_unpaused(ctx
)) {
670 _mesa_error(ctx
, GL_INVALID_OPERATION
,
671 "%s(transform feedback active)", caller
);
676 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(count)", caller
);
680 if (!_mesa_valid_prim_mode(ctx
, mode
, caller
)) {
684 if (!valid_elements_type(ctx
, type
, caller
))
687 if (!check_valid_to_render(ctx
, caller
))
690 /* Not using a VBO for indices, so avoid NULL pointer derefs later.
692 if (!_mesa_is_bufferobj(ctx
->Array
.VAO
->IndexBufferObj
) && indices
== NULL
)
702 * Error checking for glDrawElements(). Includes parameter checking
703 * and VBO bounds checking.
704 * \return GL_TRUE if OK to render, GL_FALSE if error found
707 _mesa_validate_DrawElements(struct gl_context
*ctx
,
708 GLenum mode
, GLsizei count
, GLenum type
,
709 const GLvoid
*indices
)
711 FLUSH_CURRENT(ctx
, 0);
713 return validate_DrawElements_common(ctx
, mode
, count
, type
, indices
,
719 * Error checking for glMultiDrawElements(). Includes parameter checking
720 * and VBO bounds checking.
721 * \return GL_TRUE if OK to render, GL_FALSE if error found
724 _mesa_validate_MultiDrawElements(struct gl_context
*ctx
,
725 GLenum mode
, const GLsizei
*count
,
726 GLenum type
, const GLvoid
* const *indices
,
731 FLUSH_CURRENT(ctx
, 0);
733 for (i
= 0; i
< primcount
; i
++) {
735 _mesa_error(ctx
, GL_INVALID_VALUE
,
736 "glMultiDrawElements(count)" );
741 if (!_mesa_valid_prim_mode(ctx
, mode
, "glMultiDrawElements")) {
745 if (!valid_elements_type(ctx
, type
, "glMultiDrawElements"))
748 if (!check_valid_to_render(ctx
, "glMultiDrawElements"))
751 /* Not using a VBO for indices, so avoid NULL pointer derefs later.
753 if (!_mesa_is_bufferobj(ctx
->Array
.VAO
->IndexBufferObj
)) {
754 for (i
= 0; i
< primcount
; i
++) {
765 * Error checking for glDrawRangeElements(). Includes parameter checking
766 * and VBO bounds checking.
767 * \return GL_TRUE if OK to render, GL_FALSE if error found
770 _mesa_validate_DrawRangeElements(struct gl_context
*ctx
, GLenum mode
,
771 GLuint start
, GLuint end
,
772 GLsizei count
, GLenum type
,
773 const GLvoid
*indices
)
775 FLUSH_CURRENT(ctx
, 0);
778 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDrawRangeElements(end<start)");
782 return validate_DrawElements_common(ctx
, mode
, count
, type
, indices
,
783 "glDrawRangeElements");
787 validate_draw_arrays(struct gl_context
*ctx
, const char *func
,
788 GLenum mode
, GLsizei count
, GLsizei numInstances
)
790 struct gl_transform_feedback_object
*xfb_obj
791 = ctx
->TransformFeedback
.CurrentObject
;
792 FLUSH_CURRENT(ctx
, 0);
795 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(count)", func
);
799 if (!_mesa_valid_prim_mode(ctx
, mode
, func
))
802 if (!check_valid_to_render(ctx
, func
))
805 /* From the GLES3 specification, section 2.14.2 (Transform Feedback
806 * Primitive Capture):
808 * The error INVALID_OPERATION is generated by DrawArrays and
809 * DrawArraysInstanced if recording the vertices of a primitive to the
810 * buffer objects being used for transform feedback purposes would result
811 * in either exceeding the limits of any buffer object’s size, or in
812 * exceeding the end position offset + size − 1, as set by
815 * This is in contrast to the behaviour of desktop GL, where the extra
816 * primitives are silently dropped from the transform feedback buffer.
818 * This text is removed in ES 3.2, presumably because it's not really
819 * implementable with geometry and tessellation shaders. In fact,
820 * the OES_geometry_shader spec says:
822 * "(13) Does this extension change how transform feedback operates
823 * compared to unextended OpenGL ES 3.0 or 3.1?
825 * RESOLVED: Yes. Because dynamic geometry amplification in a geometry
826 * shader can make it difficult if not impossible to predict the amount
827 * of geometry that may be generated in advance of executing the shader,
828 * the draw-time error for transform feedback buffer overflow conditions
829 * is removed and replaced with the GL behavior (primitives are not
830 * written and the corresponding counter is not updated)..."
832 if (_mesa_is_gles3(ctx
) && _mesa_is_xfb_active_and_unpaused(ctx
) &&
833 !_mesa_has_OES_geometry_shader(ctx
) &&
834 !_mesa_has_OES_tessellation_shader(ctx
)) {
835 size_t prim_count
= vbo_count_tessellated_primitives(mode
, count
, 1);
836 if (xfb_obj
->GlesRemainingPrims
< prim_count
) {
837 _mesa_error(ctx
, GL_INVALID_OPERATION
,
838 "%s(exceeds transform feedback size)", func
);
841 xfb_obj
->GlesRemainingPrims
-= prim_count
;
851 * Called from the tnl module to error check the function parameters and
852 * verify that we really can draw something.
853 * \return GL_TRUE if OK to render, GL_FALSE if error found
856 _mesa_validate_DrawArrays(struct gl_context
*ctx
, GLenum mode
, GLsizei count
)
858 return validate_draw_arrays(ctx
, "glDrawArrays", mode
, count
, 1);
863 _mesa_validate_DrawArraysInstanced(struct gl_context
*ctx
, GLenum mode
, GLint first
,
864 GLsizei count
, GLsizei numInstances
)
867 _mesa_error(ctx
, GL_INVALID_VALUE
,
868 "glDrawArraysInstanced(start=%d)", first
);
872 if (numInstances
<= 0) {
873 if (numInstances
< 0)
874 _mesa_error(ctx
, GL_INVALID_VALUE
,
875 "glDrawArraysInstanced(numInstances=%d)", numInstances
);
879 return validate_draw_arrays(ctx
, "glDrawArraysInstanced", mode
, count
, 1);
884 _mesa_validate_DrawElementsInstanced(struct gl_context
*ctx
,
885 GLenum mode
, GLsizei count
, GLenum type
,
886 const GLvoid
*indices
, GLsizei numInstances
)
888 FLUSH_CURRENT(ctx
, 0);
890 if (numInstances
< 0) {
891 _mesa_error(ctx
, GL_INVALID_VALUE
,
892 "glDrawElementsInstanced(numInstances=%d)", numInstances
);
896 return validate_DrawElements_common(ctx
, mode
, count
, type
, indices
,
897 "glDrawElementsInstanced")
898 && (numInstances
> 0);
903 _mesa_validate_DrawTransformFeedback(struct gl_context
*ctx
,
905 struct gl_transform_feedback_object
*obj
,
907 GLsizei numInstances
)
909 FLUSH_CURRENT(ctx
, 0);
911 if (!_mesa_valid_prim_mode(ctx
, mode
, "glDrawTransformFeedback*(mode)")) {
916 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDrawTransformFeedback*(name)");
920 /* From the GL 4.5 specification, page 429:
921 * "An INVALID_VALUE error is generated if id is not the name of a
922 * transform feedback object."
924 if (!obj
->EverBound
) {
925 _mesa_error(ctx
, GL_INVALID_VALUE
, "glDrawTransformFeedback*(name)");
929 if (stream
>= ctx
->Const
.MaxVertexStreams
) {
930 _mesa_error(ctx
, GL_INVALID_VALUE
,
931 "glDrawTransformFeedbackStream*(index>=MaxVertexStream)");
935 if (!obj
->EndedAnytime
) {
936 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glDrawTransformFeedback*");
940 if (numInstances
<= 0) {
941 if (numInstances
< 0)
942 _mesa_error(ctx
, GL_INVALID_VALUE
,
943 "glDrawTransformFeedback*Instanced(numInstances=%d)",
948 if (!check_valid_to_render(ctx
, "glDrawTransformFeedback*")) {
956 valid_draw_indirect(struct gl_context
*ctx
,
957 GLenum mode
, const GLvoid
*indirect
,
958 GLsizei size
, const char *name
)
960 const uint64_t end
= (uint64_t) (uintptr_t) indirect
+ size
;
962 /* OpenGL ES 3.1 spec. section 10.5:
964 * "DrawArraysIndirect requires that all data sourced for the
965 * command, including the DrawArraysIndirectCommand
966 * structure, be in buffer objects, and may not be called when
967 * the default vertex array object is bound."
969 if (ctx
->Array
.VAO
== ctx
->Array
.DefaultVAO
) {
970 _mesa_error(ctx
, GL_INVALID_OPERATION
, "(no VAO bound)");
974 /* From OpenGL ES 3.1 spec. section 10.5:
975 * "An INVALID_OPERATION error is generated if zero is bound to
976 * VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER or to any enabled
979 * Here we check that for each enabled vertex array we have a vertex
982 if (_mesa_is_gles31(ctx
) &&
983 ctx
->Array
.VAO
->_Enabled
& ~ctx
->Array
.VAO
->VertexAttribBufferMask
) {
984 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s(No VBO bound)", name
);
988 if (!_mesa_valid_prim_mode(ctx
, mode
, name
))
991 /* OpenGL ES 3.1 specification, section 10.5:
993 * "An INVALID_OPERATION error is generated if
994 * transform feedback is active and not paused."
996 * The OES_geometry_shader spec says:
998 * On p. 250 in the errors section for the DrawArraysIndirect command,
999 * and on p. 254 in the errors section for the DrawElementsIndirect
1000 * command, delete the errors which state:
1002 * "An INVALID_OPERATION error is generated if transform feedback is
1003 * active and not paused."
1005 * (thus allowing transform feedback to work with indirect draw commands).
1007 if (_mesa_is_gles31(ctx
) && !ctx
->Extensions
.OES_geometry_shader
&&
1008 _mesa_is_xfb_active_and_unpaused(ctx
)) {
1009 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1010 "%s(TransformFeedback is active and not paused)", name
);
1013 /* From OpenGL version 4.4. section 10.5
1014 * and OpenGL ES 3.1, section 10.6:
1016 * "An INVALID_VALUE error is generated if indirect is not a
1017 * multiple of the size, in basic machine units, of uint."
1019 if ((GLsizeiptr
)indirect
& (sizeof(GLuint
) - 1)) {
1020 _mesa_error(ctx
, GL_INVALID_VALUE
,
1021 "%s(indirect is not aligned)", name
);
1025 if (!_mesa_is_bufferobj(ctx
->DrawIndirectBuffer
)) {
1026 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1027 "%s: no buffer bound to DRAW_INDIRECT_BUFFER", name
);
1031 if (_mesa_check_disallowed_mapping(ctx
->DrawIndirectBuffer
)) {
1032 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1033 "%s(DRAW_INDIRECT_BUFFER is mapped)", name
);
1037 /* From the ARB_draw_indirect specification:
1038 * "An INVALID_OPERATION error is generated if the commands source data
1039 * beyond the end of the buffer object [...]"
1041 if (ctx
->DrawIndirectBuffer
->Size
< end
) {
1042 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1043 "%s(DRAW_INDIRECT_BUFFER too small)", name
);
1047 if (!check_valid_to_render(ctx
, name
))
1053 static inline GLboolean
1054 valid_draw_indirect_elements(struct gl_context
*ctx
,
1055 GLenum mode
, GLenum type
, const GLvoid
*indirect
,
1056 GLsizeiptr size
, const char *name
)
1058 if (!valid_elements_type(ctx
, type
, name
))
1062 * Unlike regular DrawElementsInstancedBaseVertex commands, the indices
1063 * may not come from a client array and must come from an index buffer.
1064 * If no element array buffer is bound, an INVALID_OPERATION error is
1067 if (!_mesa_is_bufferobj(ctx
->Array
.VAO
->IndexBufferObj
)) {
1068 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1069 "%s(no buffer bound to GL_ELEMENT_ARRAY_BUFFER)", name
);
1073 return valid_draw_indirect(ctx
, mode
, indirect
, size
, name
);
1076 static inline GLboolean
1077 valid_draw_indirect_multi(struct gl_context
*ctx
,
1078 GLsizei primcount
, GLsizei stride
,
1082 /* From the ARB_multi_draw_indirect specification:
1083 * "INVALID_VALUE is generated by MultiDrawArraysIndirect or
1084 * MultiDrawElementsIndirect if <primcount> is negative."
1086 * "<primcount> must be positive, otherwise an INVALID_VALUE error will
1089 if (primcount
< 0) {
1090 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(primcount < 0)", name
);
1095 /* From the ARB_multi_draw_indirect specification:
1096 * "<stride> must be a multiple of four, otherwise an INVALID_VALUE
1097 * error is generated."
1100 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(stride %% 4)", name
);
1108 _mesa_validate_DrawArraysIndirect(struct gl_context
*ctx
,
1110 const GLvoid
*indirect
)
1112 const unsigned drawArraysNumParams
= 4;
1114 FLUSH_CURRENT(ctx
, 0);
1116 return valid_draw_indirect(ctx
, mode
,
1117 indirect
, drawArraysNumParams
* sizeof(GLuint
),
1118 "glDrawArraysIndirect");
1122 _mesa_validate_DrawElementsIndirect(struct gl_context
*ctx
,
1123 GLenum mode
, GLenum type
,
1124 const GLvoid
*indirect
)
1126 const unsigned drawElementsNumParams
= 5;
1128 FLUSH_CURRENT(ctx
, 0);
1130 return valid_draw_indirect_elements(ctx
, mode
, type
,
1131 indirect
, drawElementsNumParams
* sizeof(GLuint
),
1132 "glDrawElementsIndirect");
1136 _mesa_validate_MultiDrawArraysIndirect(struct gl_context
*ctx
,
1138 const GLvoid
*indirect
,
1139 GLsizei primcount
, GLsizei stride
)
1141 GLsizeiptr size
= 0;
1142 const unsigned drawArraysNumParams
= 4;
1144 FLUSH_CURRENT(ctx
, 0);
1146 /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */
1147 assert(stride
!= 0);
1149 if (!valid_draw_indirect_multi(ctx
, primcount
, stride
,
1150 "glMultiDrawArraysIndirect"))
1153 /* number of bytes of the indirect buffer which will be read */
1155 ? (primcount
- 1) * stride
+ drawArraysNumParams
* sizeof(GLuint
)
1158 if (!valid_draw_indirect(ctx
, mode
, indirect
, size
,
1159 "glMultiDrawArraysIndirect"))
1166 _mesa_validate_MultiDrawElementsIndirect(struct gl_context
*ctx
,
1167 GLenum mode
, GLenum type
,
1168 const GLvoid
*indirect
,
1169 GLsizei primcount
, GLsizei stride
)
1171 GLsizeiptr size
= 0;
1172 const unsigned drawElementsNumParams
= 5;
1174 FLUSH_CURRENT(ctx
, 0);
1176 /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */
1177 assert(stride
!= 0);
1179 if (!valid_draw_indirect_multi(ctx
, primcount
, stride
,
1180 "glMultiDrawElementsIndirect"))
1183 /* number of bytes of the indirect buffer which will be read */
1185 ? (primcount
- 1) * stride
+ drawElementsNumParams
* sizeof(GLuint
)
1188 if (!valid_draw_indirect_elements(ctx
, mode
, type
,
1190 "glMultiDrawElementsIndirect"))
1197 valid_draw_indirect_parameters(struct gl_context
*ctx
,
1201 /* From the ARB_indirect_parameters specification:
1202 * "INVALID_VALUE is generated by MultiDrawArraysIndirectCountARB or
1203 * MultiDrawElementsIndirectCountARB if <drawcount> is not a multiple of
1206 if (drawcount
& 3) {
1207 _mesa_error(ctx
, GL_INVALID_VALUE
,
1208 "%s(drawcount is not a multiple of 4)", name
);
1212 /* From the ARB_indirect_parameters specification:
1213 * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or
1214 * MultiDrawElementsIndirectCountARB if no buffer is bound to the
1215 * PARAMETER_BUFFER_ARB binding point."
1217 if (!_mesa_is_bufferobj(ctx
->ParameterBuffer
)) {
1218 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1219 "%s: no buffer bound to PARAMETER_BUFFER", name
);
1223 if (_mesa_check_disallowed_mapping(ctx
->ParameterBuffer
)) {
1224 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1225 "%s(PARAMETER_BUFFER is mapped)", name
);
1229 /* From the ARB_indirect_parameters specification:
1230 * "INVALID_OPERATION is generated by MultiDrawArraysIndirectCountARB or
1231 * MultiDrawElementsIndirectCountARB if reading a <sizei> typed value
1232 * from the buffer bound to the PARAMETER_BUFFER_ARB target at the offset
1233 * specified by <drawcount> would result in an out-of-bounds access."
1235 if (ctx
->ParameterBuffer
->Size
< drawcount
+ sizeof(GLsizei
)) {
1236 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1237 "%s(PARAMETER_BUFFER too small)", name
);
1245 _mesa_validate_MultiDrawArraysIndirectCount(struct gl_context
*ctx
,
1249 GLsizei maxdrawcount
,
1252 GLsizeiptr size
= 0;
1253 const unsigned drawArraysNumParams
= 4;
1255 FLUSH_CURRENT(ctx
, 0);
1257 /* caller has converted stride==0 to drawArraysNumParams * sizeof(GLuint) */
1258 assert(stride
!= 0);
1260 if (!valid_draw_indirect_multi(ctx
, maxdrawcount
, stride
,
1261 "glMultiDrawArraysIndirectCountARB"))
1264 /* number of bytes of the indirect buffer which will be read */
1266 ? (maxdrawcount
- 1) * stride
+ drawArraysNumParams
* sizeof(GLuint
)
1269 if (!valid_draw_indirect(ctx
, mode
, (void *)indirect
, size
,
1270 "glMultiDrawArraysIndirectCountARB"))
1273 return valid_draw_indirect_parameters(
1274 ctx
, "glMultiDrawArraysIndirectCountARB", drawcount
);
1278 _mesa_validate_MultiDrawElementsIndirectCount(struct gl_context
*ctx
,
1279 GLenum mode
, GLenum type
,
1282 GLsizei maxdrawcount
,
1285 GLsizeiptr size
= 0;
1286 const unsigned drawElementsNumParams
= 5;
1288 FLUSH_CURRENT(ctx
, 0);
1290 /* caller has converted stride==0 to drawElementsNumParams * sizeof(GLuint) */
1291 assert(stride
!= 0);
1293 if (!valid_draw_indirect_multi(ctx
, maxdrawcount
, stride
,
1294 "glMultiDrawElementsIndirectCountARB"))
1297 /* number of bytes of the indirect buffer which will be read */
1299 ? (maxdrawcount
- 1) * stride
+ drawElementsNumParams
* sizeof(GLuint
)
1302 if (!valid_draw_indirect_elements(ctx
, mode
, type
,
1303 (void *)indirect
, size
,
1304 "glMultiDrawElementsIndirectCountARB"))
1307 return valid_draw_indirect_parameters(
1308 ctx
, "glMultiDrawElementsIndirectCountARB", drawcount
);
1312 check_valid_to_compute(struct gl_context
*ctx
, const char *function
)
1314 if (!_mesa_has_compute_shaders(ctx
)) {
1315 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1316 "unsupported function (%s) called",
1321 /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
1323 * "An INVALID_OPERATION error is generated if there is no active program
1324 * for the compute shader stage."
1326 if (ctx
->_Shader
->CurrentProgram
[MESA_SHADER_COMPUTE
] == NULL
) {
1327 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1328 "%s(no active compute shader)",
1337 _mesa_validate_DispatchCompute(struct gl_context
*ctx
,
1338 const GLuint
*num_groups
)
1341 FLUSH_CURRENT(ctx
, 0);
1343 if (!check_valid_to_compute(ctx
, "glDispatchCompute"))
1346 for (i
= 0; i
< 3; i
++) {
1347 /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
1349 * "An INVALID_VALUE error is generated if any of num_groups_x,
1350 * num_groups_y and num_groups_z are greater than or equal to the
1351 * maximum work group count for the corresponding dimension."
1353 * However, the "or equal to" portions appears to be a specification
1354 * bug. In all other areas, the specification appears to indicate that
1355 * the number of workgroups can match the MAX_COMPUTE_WORK_GROUP_COUNT
1356 * value. For example, under DispatchComputeIndirect:
1358 * "If any of num_groups_x, num_groups_y or num_groups_z is greater than
1359 * the value of MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding
1360 * dimension then the results are undefined."
1362 * Additionally, the OpenGLES 3.1 specification does not contain "or
1363 * equal to" as an error condition.
1365 if (num_groups
[i
] > ctx
->Const
.MaxComputeWorkGroupCount
[i
]) {
1366 _mesa_error(ctx
, GL_INVALID_VALUE
,
1367 "glDispatchCompute(num_groups_%c)", 'x' + i
);
1372 /* The ARB_compute_variable_group_size spec says:
1374 * "An INVALID_OPERATION error is generated by DispatchCompute if the active
1375 * program for the compute shader stage has a variable work group size."
1377 struct gl_program
*prog
= ctx
->_Shader
->CurrentProgram
[MESA_SHADER_COMPUTE
];
1378 if (prog
->info
.cs
.local_size_variable
) {
1379 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1380 "glDispatchCompute(variable work group size forbidden)");
1388 _mesa_validate_DispatchComputeGroupSizeARB(struct gl_context
*ctx
,
1389 const GLuint
*num_groups
,
1390 const GLuint
*group_size
)
1392 GLuint total_invocations
= 1;
1395 FLUSH_CURRENT(ctx
, 0);
1397 if (!check_valid_to_compute(ctx
, "glDispatchComputeGroupSizeARB"))
1400 /* The ARB_compute_variable_group_size spec says:
1402 * "An INVALID_OPERATION error is generated by
1403 * DispatchComputeGroupSizeARB if the active program for the compute
1404 * shader stage has a fixed work group size."
1406 struct gl_program
*prog
= ctx
->_Shader
->CurrentProgram
[MESA_SHADER_COMPUTE
];
1407 if (!prog
->info
.cs
.local_size_variable
) {
1408 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1409 "glDispatchComputeGroupSizeARB(fixed work group size "
1414 for (i
= 0; i
< 3; i
++) {
1415 /* The ARB_compute_variable_group_size spec says:
1417 * "An INVALID_VALUE error is generated if any of num_groups_x,
1418 * num_groups_y and num_groups_z are greater than or equal to the
1419 * maximum work group count for the corresponding dimension."
1421 if (num_groups
[i
] > ctx
->Const
.MaxComputeWorkGroupCount
[i
]) {
1422 _mesa_error(ctx
, GL_INVALID_VALUE
,
1423 "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i
);
1427 /* The ARB_compute_variable_group_size spec says:
1429 * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
1430 * any of <group_size_x>, <group_size_y>, or <group_size_z> is less than
1431 * or equal to zero or greater than the maximum local work group size
1432 * for compute shaders with variable group size
1433 * (MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) in the corresponding
1436 * However, the "less than" is a spec bug because they are declared as
1437 * unsigned integers.
1439 if (group_size
[i
] == 0 ||
1440 group_size
[i
] > ctx
->Const
.MaxComputeVariableGroupSize
[i
]) {
1441 _mesa_error(ctx
, GL_INVALID_VALUE
,
1442 "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i
);
1446 total_invocations
*= group_size
[i
];
1449 /* The ARB_compute_variable_group_size spec says:
1451 * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
1452 * the product of <group_size_x>, <group_size_y>, and <group_size_z> exceeds
1453 * the implementation-dependent maximum local work group invocation count
1454 * for compute shaders with variable group size
1455 * (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)."
1457 if (total_invocations
> ctx
->Const
.MaxComputeVariableGroupInvocations
) {
1458 _mesa_error(ctx
, GL_INVALID_VALUE
,
1459 "glDispatchComputeGroupSizeARB(product of local_sizes "
1460 "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB "
1461 "(%d > %d))", total_invocations
,
1462 ctx
->Const
.MaxComputeVariableGroupInvocations
);
1470 valid_dispatch_indirect(struct gl_context
*ctx
,
1472 GLsizei size
, const char *name
)
1474 const uint64_t end
= (uint64_t) indirect
+ size
;
1476 if (!check_valid_to_compute(ctx
, name
))
1479 /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
1481 * "An INVALID_VALUE error is generated if indirect is negative or is not a
1482 * multiple of four."
1484 if (indirect
& (sizeof(GLuint
) - 1)) {
1485 _mesa_error(ctx
, GL_INVALID_VALUE
,
1486 "%s(indirect is not aligned)", name
);
1491 _mesa_error(ctx
, GL_INVALID_VALUE
,
1492 "%s(indirect is less than zero)", name
);
1496 /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
1498 * "An INVALID_OPERATION error is generated if no buffer is bound to the
1499 * DRAW_INDIRECT_BUFFER binding, or if the command would source data
1500 * beyond the end of the buffer object."
1502 if (!_mesa_is_bufferobj(ctx
->DispatchIndirectBuffer
)) {
1503 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1504 "%s: no buffer bound to DISPATCH_INDIRECT_BUFFER", name
);
1508 if (_mesa_check_disallowed_mapping(ctx
->DispatchIndirectBuffer
)) {
1509 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1510 "%s(DISPATCH_INDIRECT_BUFFER is mapped)", name
);
1514 if (ctx
->DispatchIndirectBuffer
->Size
< end
) {
1515 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1516 "%s(DISPATCH_INDIRECT_BUFFER too small)", name
);
1520 /* The ARB_compute_variable_group_size spec says:
1522 * "An INVALID_OPERATION error is generated if the active program for the
1523 * compute shader stage has a variable work group size."
1525 struct gl_program
*prog
= ctx
->_Shader
->CurrentProgram
[MESA_SHADER_COMPUTE
];
1526 if (prog
->info
.cs
.local_size_variable
) {
1527 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1528 "%s(variable work group size forbidden)", name
);
1536 _mesa_validate_DispatchComputeIndirect(struct gl_context
*ctx
,
1539 FLUSH_CURRENT(ctx
, 0);
1541 return valid_dispatch_indirect(ctx
, indirect
, 3 * sizeof(GLuint
),
1542 "glDispatchComputeIndirect");