1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters
8
9 #include "libANGLE/validationES31_autogen.h"
10
11 #include "libANGLE/Context.h"
12 #include "libANGLE/ErrorStrings.h"
13 #include "libANGLE/Framebuffer.h"
14 #include "libANGLE/ProgramExecutable.h"
15 #include "libANGLE/VertexArray.h"
16 #include "libANGLE/validationES.h"
17 #include "libANGLE/validationES2_autogen.h"
18 #include "libANGLE/validationES31.h"
19 #include "libANGLE/validationES3_autogen.h"
20
21 #include "common/utilities.h"
22
23 using namespace angle;
24
25 namespace gl
26 {
27 using namespace err;
28
29 namespace
30 {
31
ValidateNamedProgramInterface(GLenum programInterface)32 bool ValidateNamedProgramInterface(GLenum programInterface)
33 {
34 switch (programInterface)
35 {
36 case GL_UNIFORM:
37 case GL_UNIFORM_BLOCK:
38 case GL_PROGRAM_INPUT:
39 case GL_PROGRAM_OUTPUT:
40 case GL_TRANSFORM_FEEDBACK_VARYING:
41 case GL_BUFFER_VARIABLE:
42 case GL_SHADER_STORAGE_BLOCK:
43 return true;
44 default:
45 return false;
46 }
47 }
48
ValidateLocationProgramInterface(GLenum programInterface)49 bool ValidateLocationProgramInterface(GLenum programInterface)
50 {
51 switch (programInterface)
52 {
53 case GL_UNIFORM:
54 case GL_PROGRAM_INPUT:
55 case GL_PROGRAM_OUTPUT:
56 return true;
57 default:
58 return false;
59 }
60 }
61
ValidateProgramInterface(GLenum programInterface)62 bool ValidateProgramInterface(GLenum programInterface)
63 {
64 return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
65 ValidateNamedProgramInterface(programInterface));
66 }
67
ValidateProgramResourceProperty(const Context * context,GLenum prop)68 bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
69 {
70 ASSERT(context);
71 switch (prop)
72 {
73 case GL_ACTIVE_VARIABLES:
74 case GL_BUFFER_BINDING:
75 case GL_NUM_ACTIVE_VARIABLES:
76
77 case GL_ARRAY_SIZE:
78
79 case GL_ARRAY_STRIDE:
80 case GL_BLOCK_INDEX:
81 case GL_IS_ROW_MAJOR:
82 case GL_MATRIX_STRIDE:
83
84 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
85
86 case GL_BUFFER_DATA_SIZE:
87
88 case GL_LOCATION:
89
90 case GL_NAME_LENGTH:
91
92 case GL_OFFSET:
93
94 case GL_REFERENCED_BY_VERTEX_SHADER:
95 case GL_REFERENCED_BY_FRAGMENT_SHADER:
96 case GL_REFERENCED_BY_COMPUTE_SHADER:
97
98 case GL_TOP_LEVEL_ARRAY_SIZE:
99 case GL_TOP_LEVEL_ARRAY_STRIDE:
100
101 case GL_TYPE:
102 return true;
103
104 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
105 return context->getExtensions().geometryShaderAny() ||
106 context->getClientVersion() >= ES_3_2;
107
108 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
109 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
110 case GL_IS_PER_PATCH_EXT:
111 return context->getExtensions().tessellationShaderEXT ||
112 context->getClientVersion() >= ES_3_2;
113
114 case GL_LOCATION_INDEX_EXT:
115 return context->getExtensions().blendFuncExtended;
116
117 default:
118 return false;
119 }
120 }
121
122 // GLES 3.10 spec: Page 82 -- Table 7.2
ValidateProgramResourcePropertyByInterface(GLenum prop,GLenum programInterface)123 bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
124 {
125 switch (prop)
126 {
127 case GL_ACTIVE_VARIABLES:
128 case GL_BUFFER_BINDING:
129 case GL_NUM_ACTIVE_VARIABLES:
130 {
131 switch (programInterface)
132 {
133 case GL_ATOMIC_COUNTER_BUFFER:
134 case GL_SHADER_STORAGE_BLOCK:
135 case GL_UNIFORM_BLOCK:
136 return true;
137 default:
138 return false;
139 }
140 }
141
142 case GL_ARRAY_SIZE:
143 {
144 switch (programInterface)
145 {
146 case GL_BUFFER_VARIABLE:
147 case GL_PROGRAM_INPUT:
148 case GL_PROGRAM_OUTPUT:
149 case GL_TRANSFORM_FEEDBACK_VARYING:
150 case GL_UNIFORM:
151 return true;
152 default:
153 return false;
154 }
155 }
156
157 case GL_ARRAY_STRIDE:
158 case GL_BLOCK_INDEX:
159 case GL_IS_ROW_MAJOR:
160 case GL_MATRIX_STRIDE:
161 {
162 switch (programInterface)
163 {
164 case GL_BUFFER_VARIABLE:
165 case GL_UNIFORM:
166 return true;
167 default:
168 return false;
169 }
170 }
171
172 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
173 {
174 if (programInterface == GL_UNIFORM)
175 {
176 return true;
177 }
178 return false;
179 }
180
181 case GL_BUFFER_DATA_SIZE:
182 {
183 switch (programInterface)
184 {
185 case GL_ATOMIC_COUNTER_BUFFER:
186 case GL_SHADER_STORAGE_BLOCK:
187 case GL_UNIFORM_BLOCK:
188 return true;
189 default:
190 return false;
191 }
192 }
193
194 case GL_LOCATION:
195 {
196 return ValidateLocationProgramInterface(programInterface);
197 }
198
199 case GL_LOCATION_INDEX_EXT:
200 {
201 // EXT_blend_func_extended
202 return (programInterface == GL_PROGRAM_OUTPUT);
203 }
204
205 case GL_NAME_LENGTH:
206 {
207 return ValidateNamedProgramInterface(programInterface);
208 }
209
210 case GL_OFFSET:
211 {
212 switch (programInterface)
213 {
214 case GL_BUFFER_VARIABLE:
215 case GL_UNIFORM:
216 return true;
217 default:
218 return false;
219 }
220 }
221
222 case GL_REFERENCED_BY_VERTEX_SHADER:
223 case GL_REFERENCED_BY_FRAGMENT_SHADER:
224 case GL_REFERENCED_BY_COMPUTE_SHADER:
225 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
226 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
227 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
228 {
229 switch (programInterface)
230 {
231 case GL_ATOMIC_COUNTER_BUFFER:
232 case GL_BUFFER_VARIABLE:
233 case GL_PROGRAM_INPUT:
234 case GL_PROGRAM_OUTPUT:
235 case GL_SHADER_STORAGE_BLOCK:
236 case GL_UNIFORM:
237 case GL_UNIFORM_BLOCK:
238 return true;
239 default:
240 return false;
241 }
242 }
243
244 case GL_TOP_LEVEL_ARRAY_SIZE:
245 case GL_TOP_LEVEL_ARRAY_STRIDE:
246 {
247 if (programInterface == GL_BUFFER_VARIABLE)
248 {
249 return true;
250 }
251 return false;
252 }
253
254 case GL_TYPE:
255 {
256 switch (programInterface)
257 {
258 case GL_BUFFER_VARIABLE:
259 case GL_PROGRAM_INPUT:
260 case GL_PROGRAM_OUTPUT:
261 case GL_TRANSFORM_FEEDBACK_VARYING:
262 case GL_UNIFORM:
263 return true;
264 default:
265 return false;
266 }
267 }
268 case GL_IS_PER_PATCH_EXT:
269 switch (programInterface)
270 {
271 case GL_PROGRAM_INPUT:
272 case GL_PROGRAM_OUTPUT:
273 return true;
274 }
275 return false;
276
277 default:
278 return false;
279 }
280 }
281
ValidateProgramResourceIndex(const Program * programObject,GLenum programInterface,GLuint index)282 bool ValidateProgramResourceIndex(const Program *programObject,
283 GLenum programInterface,
284 GLuint index)
285 {
286 switch (programInterface)
287 {
288 case GL_PROGRAM_INPUT:
289 return (index <
290 static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
291
292 case GL_PROGRAM_OUTPUT:
293 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
294
295 case GL_UNIFORM:
296 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
297
298 case GL_BUFFER_VARIABLE:
299 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
300
301 case GL_SHADER_STORAGE_BLOCK:
302 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
303
304 case GL_UNIFORM_BLOCK:
305 return (index < programObject->getActiveUniformBlockCount());
306
307 case GL_ATOMIC_COUNTER_BUFFER:
308 return (index < programObject->getActiveAtomicCounterBufferCount());
309
310 case GL_TRANSFORM_FEEDBACK_VARYING:
311 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
312
313 default:
314 UNREACHABLE();
315 return false;
316 }
317 }
318
ValidateProgramUniformBase(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count)319 bool ValidateProgramUniformBase(const Context *context,
320 GLenum valueType,
321 ShaderProgramID program,
322 UniformLocation location,
323 GLsizei count)
324 {
325 const LinkedUniform *uniform = nullptr;
326 Program *programObject = GetValidProgram(context, program);
327 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
328 ValidateUniformValue(context, valueType, uniform->type);
329 }
330
ValidateProgramUniformMatrixBase(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose)331 bool ValidateProgramUniformMatrixBase(const Context *context,
332 GLenum valueType,
333 ShaderProgramID program,
334 UniformLocation location,
335 GLsizei count,
336 GLboolean transpose)
337 {
338 const LinkedUniform *uniform = nullptr;
339 Program *programObject = GetValidProgram(context, program);
340 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
341 ValidateUniformMatrixValue(context, valueType, uniform->type);
342 }
343
ValidateVertexAttribFormatCommon(const Context * context,GLuint relativeOffset)344 bool ValidateVertexAttribFormatCommon(const Context *context, GLuint relativeOffset)
345 {
346 if (context->getClientVersion() < ES_3_1)
347 {
348 context->validationError(GL_INVALID_OPERATION, kES31Required);
349 return false;
350 }
351
352 const Caps &caps = context->getCaps();
353 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
354 {
355 context->validationError(GL_INVALID_VALUE, kRelativeOffsetTooLarge);
356 return false;
357 }
358
359 // [OpenGL ES 3.1] Section 10.3.1 page 243:
360 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
361 if (context->getState().getVertexArrayId().value == 0)
362 {
363 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
364 return false;
365 }
366
367 return true;
368 }
369
370 } // anonymous namespace
371
ValidateGetBooleani_v(const Context * context,GLenum target,GLuint index,const GLboolean * data)372 bool ValidateGetBooleani_v(const Context *context,
373 GLenum target,
374 GLuint index,
375 const GLboolean *data)
376 {
377 if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny())
378 {
379 context->validationError(GL_INVALID_OPERATION,
380 kES31OrDrawBuffersIndexedExtensionNotAvailable);
381 return false;
382 }
383
384 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
385 {
386 return false;
387 }
388
389 return true;
390 }
391
ValidateGetBooleani_vRobustANGLE(const Context * context,GLenum target,GLuint index,GLsizei bufSize,const GLsizei * length,const GLboolean * data)392 bool ValidateGetBooleani_vRobustANGLE(const Context *context,
393 GLenum target,
394 GLuint index,
395 GLsizei bufSize,
396 const GLsizei *length,
397 const GLboolean *data)
398 {
399 if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny())
400 {
401 context->validationError(GL_INVALID_OPERATION,
402 kES31OrDrawBuffersIndexedExtensionNotAvailable);
403 return false;
404 }
405
406 if (!ValidateRobustEntryPoint(context, bufSize))
407 {
408 return false;
409 }
410
411 GLsizei numParams = 0;
412
413 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
414 {
415 return false;
416 }
417
418 if (!ValidateRobustBufferSize(context, bufSize, numParams))
419 {
420 return false;
421 }
422
423 SetRobustLengthParam(length, numParams);
424 return true;
425 }
426
ValidateDrawIndirectBase(const Context * context,PrimitiveMode mode,const void * indirect)427 bool ValidateDrawIndirectBase(const Context *context, PrimitiveMode mode, const void *indirect)
428 {
429 if (context->getClientVersion() < ES_3_1)
430 {
431 context->validationError(GL_INVALID_OPERATION, kES31Required);
432 return false;
433 }
434
435 // Here the third parameter 1 is only to pass the count validation.
436 if (!ValidateDrawBase(context, mode))
437 {
438 return false;
439 }
440
441 const State &state = context->getState();
442
443 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
444 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
445 if (state.getVertexArrayId().value == 0)
446 {
447 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
448 return false;
449 }
450
451 if (context->getStateCache().hasAnyActiveClientAttrib())
452 {
453 context->validationError(GL_INVALID_OPERATION, kClientDataInVertexArray);
454 return false;
455 }
456
457 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
458 if (!drawIndirectBuffer)
459 {
460 context->validationError(GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
461 return false;
462 }
463
464 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
465 // machine units, of uint.
466 GLint64 offset = reinterpret_cast<GLint64>(indirect);
467 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
468 {
469 context->validationError(GL_INVALID_VALUE, kInvalidIndirectOffset);
470 return false;
471 }
472
473 return true;
474 }
475
ValidateDrawArraysIndirect(const Context * context,PrimitiveMode mode,const void * indirect)476 bool ValidateDrawArraysIndirect(const Context *context, PrimitiveMode mode, const void *indirect)
477 {
478 const State &state = context->getState();
479 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
480 if (curTransformFeedback && curTransformFeedback->isActive() &&
481 !curTransformFeedback->isPaused())
482 {
483 // EXT_geometry_shader allows transform feedback to work with all draw commands.
484 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
485 if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
486 {
487 if (!ValidateTransformFeedbackPrimitiveMode(
488 context, curTransformFeedback->getPrimitiveMode(), mode))
489 {
490 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
491 return false;
492 }
493 }
494 else
495 {
496 // An INVALID_OPERATION error is generated if transform feedback is active and not
497 // paused.
498 context->validationError(GL_INVALID_OPERATION,
499 kUnsupportedDrawModeForTransformFeedback);
500 return false;
501 }
502 }
503
504 if (!ValidateDrawIndirectBase(context, mode, indirect))
505 return false;
506
507 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
508 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
509 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
510 // which's size is 4 * sizeof(uint).
511 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
512 if (!checkedSum.IsValid() ||
513 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
514 {
515 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
516 return false;
517 }
518
519 return true;
520 }
521
ValidateDrawElementsIndirect(const Context * context,PrimitiveMode mode,DrawElementsType type,const void * indirect)522 bool ValidateDrawElementsIndirect(const Context *context,
523 PrimitiveMode mode,
524 DrawElementsType type,
525 const void *indirect)
526 {
527 if (!ValidateDrawElementsBase(context, mode, type))
528 {
529 return false;
530 }
531
532 const State &state = context->getState();
533 const VertexArray *vao = state.getVertexArray();
534 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
535 if (!elementArrayBuffer)
536 {
537 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
538 return false;
539 }
540
541 if (!ValidateDrawIndirectBase(context, mode, indirect))
542 return false;
543
544 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
545 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
546 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
547 // which's size is 5 * sizeof(uint).
548 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
549 if (!checkedSum.IsValid() ||
550 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
551 {
552 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
553 return false;
554 }
555
556 return true;
557 }
558
ValidateProgramUniform1iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0)559 bool ValidateProgramUniform1iBase(const Context *context,
560 ShaderProgramID program,
561 UniformLocation location,
562 GLint v0)
563 {
564 return ValidateProgramUniform1ivBase(context, program, location, 1, &v0);
565 }
566
ValidateProgramUniform2iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1)567 bool ValidateProgramUniform2iBase(const Context *context,
568 ShaderProgramID program,
569 UniformLocation location,
570 GLint v0,
571 GLint v1)
572 {
573 GLint xy[2] = {v0, v1};
574 return ValidateProgramUniform2ivBase(context, program, location, 1, xy);
575 }
576
ValidateProgramUniform3iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2)577 bool ValidateProgramUniform3iBase(const Context *context,
578 ShaderProgramID program,
579 UniformLocation location,
580 GLint v0,
581 GLint v1,
582 GLint v2)
583 {
584 GLint xyz[3] = {v0, v1, v2};
585 return ValidateProgramUniform3ivBase(context, program, location, 1, xyz);
586 }
587
ValidateProgramUniform4iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2,GLint v3)588 bool ValidateProgramUniform4iBase(const Context *context,
589 ShaderProgramID program,
590 UniformLocation location,
591 GLint v0,
592 GLint v1,
593 GLint v2,
594 GLint v3)
595 {
596 GLint xyzw[4] = {v0, v1, v2, v3};
597 return ValidateProgramUniform4ivBase(context, program, location, 1, xyzw);
598 }
599
ValidateProgramUniform1uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0)600 bool ValidateProgramUniform1uiBase(const Context *context,
601 ShaderProgramID program,
602 UniformLocation location,
603 GLuint v0)
604 {
605 return ValidateProgramUniform1uivBase(context, program, location, 1, &v0);
606 }
607
ValidateProgramUniform2uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1)608 bool ValidateProgramUniform2uiBase(const Context *context,
609 ShaderProgramID program,
610 UniformLocation location,
611 GLuint v0,
612 GLuint v1)
613 {
614 GLuint xy[2] = {v0, v1};
615 return ValidateProgramUniform2uivBase(context, program, location, 1, xy);
616 }
617
ValidateProgramUniform3uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)618 bool ValidateProgramUniform3uiBase(const Context *context,
619 ShaderProgramID program,
620 UniformLocation location,
621 GLuint v0,
622 GLuint v1,
623 GLuint v2)
624 {
625 GLuint xyz[3] = {v0, v1, v2};
626 return ValidateProgramUniform3uivBase(context, program, location, 1, xyz);
627 }
628
ValidateProgramUniform4uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)629 bool ValidateProgramUniform4uiBase(const Context *context,
630 ShaderProgramID program,
631 UniformLocation location,
632 GLuint v0,
633 GLuint v1,
634 GLuint v2,
635 GLuint v3)
636 {
637 GLuint xyzw[4] = {v0, v1, v2, v3};
638 return ValidateProgramUniform4uivBase(context, program, location, 1, xyzw);
639 }
640
ValidateProgramUniform1fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0)641 bool ValidateProgramUniform1fBase(const Context *context,
642 ShaderProgramID program,
643 UniformLocation location,
644 GLfloat v0)
645 {
646 return ValidateProgramUniform1fvBase(context, program, location, 1, &v0);
647 }
648
ValidateProgramUniform2fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1)649 bool ValidateProgramUniform2fBase(const Context *context,
650 ShaderProgramID program,
651 UniformLocation location,
652 GLfloat v0,
653 GLfloat v1)
654 {
655 GLfloat xy[2] = {v0, v1};
656 return ValidateProgramUniform2fvBase(context, program, location, 1, xy);
657 }
658
ValidateProgramUniform3fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2)659 bool ValidateProgramUniform3fBase(const Context *context,
660 ShaderProgramID program,
661 UniformLocation location,
662 GLfloat v0,
663 GLfloat v1,
664 GLfloat v2)
665 {
666 GLfloat xyz[3] = {v0, v1, v2};
667 return ValidateProgramUniform3fvBase(context, program, location, 1, xyz);
668 }
669
ValidateProgramUniform4fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)670 bool ValidateProgramUniform4fBase(const Context *context,
671 ShaderProgramID program,
672 UniformLocation location,
673 GLfloat v0,
674 GLfloat v1,
675 GLfloat v2,
676 GLfloat v3)
677 {
678 GLfloat xyzw[4] = {v0, v1, v2, v3};
679 return ValidateProgramUniform4fvBase(context, program, location, 1, xyzw);
680 }
681
ValidateProgramUniform1ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)682 bool ValidateProgramUniform1ivBase(const Context *context,
683 ShaderProgramID program,
684 UniformLocation location,
685 GLsizei count,
686 const GLint *value)
687 {
688 const LinkedUniform *uniform = nullptr;
689 Program *programObject = GetValidProgram(context, program);
690 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
691 ValidateUniform1ivValue(context, uniform->type, count, value);
692 }
693
ValidateProgramUniform2ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)694 bool ValidateProgramUniform2ivBase(const Context *context,
695 ShaderProgramID program,
696 UniformLocation location,
697 GLsizei count,
698 const GLint *value)
699 {
700 return ValidateProgramUniformBase(context, GL_INT_VEC2, program, location, count);
701 }
702
ValidateProgramUniform3ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)703 bool ValidateProgramUniform3ivBase(const Context *context,
704 ShaderProgramID program,
705 UniformLocation location,
706 GLsizei count,
707 const GLint *value)
708 {
709 return ValidateProgramUniformBase(context, GL_INT_VEC3, program, location, count);
710 }
711
ValidateProgramUniform4ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)712 bool ValidateProgramUniform4ivBase(const Context *context,
713 ShaderProgramID program,
714 UniformLocation location,
715 GLsizei count,
716 const GLint *value)
717 {
718 return ValidateProgramUniformBase(context, GL_INT_VEC4, program, location, count);
719 }
720
ValidateProgramUniform1uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)721 bool ValidateProgramUniform1uivBase(const Context *context,
722 ShaderProgramID program,
723 UniformLocation location,
724 GLsizei count,
725 const GLuint *value)
726 {
727 return ValidateProgramUniformBase(context, GL_UNSIGNED_INT, program, location, count);
728 }
729
ValidateProgramUniform2uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)730 bool ValidateProgramUniform2uivBase(const Context *context,
731 ShaderProgramID program,
732 UniformLocation location,
733 GLsizei count,
734 const GLuint *value)
735 {
736 return ValidateProgramUniformBase(context, GL_UNSIGNED_INT_VEC2, program, location, count);
737 }
738
ValidateProgramUniform3uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)739 bool ValidateProgramUniform3uivBase(const Context *context,
740 ShaderProgramID program,
741 UniformLocation location,
742 GLsizei count,
743 const GLuint *value)
744 {
745 return ValidateProgramUniformBase(context, GL_UNSIGNED_INT_VEC3, program, location, count);
746 }
747
ValidateProgramUniform4uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)748 bool ValidateProgramUniform4uivBase(const Context *context,
749 ShaderProgramID program,
750 UniformLocation location,
751 GLsizei count,
752 const GLuint *value)
753 {
754 return ValidateProgramUniformBase(context, GL_UNSIGNED_INT_VEC4, program, location, count);
755 }
756
ValidateProgramUniform1fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)757 bool ValidateProgramUniform1fvBase(const Context *context,
758 ShaderProgramID program,
759 UniformLocation location,
760 GLsizei count,
761 const GLfloat *value)
762 {
763 return ValidateProgramUniformBase(context, GL_FLOAT, program, location, count);
764 }
765
ValidateProgramUniform2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)766 bool ValidateProgramUniform2fvBase(const Context *context,
767 ShaderProgramID program,
768 UniformLocation location,
769 GLsizei count,
770 const GLfloat *value)
771 {
772 return ValidateProgramUniformBase(context, GL_FLOAT_VEC2, program, location, count);
773 }
774
ValidateProgramUniform3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)775 bool ValidateProgramUniform3fvBase(const Context *context,
776 ShaderProgramID program,
777 UniformLocation location,
778 GLsizei count,
779 const GLfloat *value)
780 {
781 return ValidateProgramUniformBase(context, GL_FLOAT_VEC3, program, location, count);
782 }
783
ValidateProgramUniform4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)784 bool ValidateProgramUniform4fvBase(const Context *context,
785 ShaderProgramID program,
786 UniformLocation location,
787 GLsizei count,
788 const GLfloat *value)
789 {
790 return ValidateProgramUniformBase(context, GL_FLOAT_VEC4, program, location, count);
791 }
792
ValidateProgramUniformMatrix2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)793 bool ValidateProgramUniformMatrix2fvBase(const Context *context,
794 ShaderProgramID program,
795 UniformLocation location,
796 GLsizei count,
797 GLboolean transpose,
798 const GLfloat *value)
799 {
800 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT2, program, location, count,
801 transpose);
802 }
803
ValidateProgramUniformMatrix3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)804 bool ValidateProgramUniformMatrix3fvBase(const Context *context,
805 ShaderProgramID program,
806 UniformLocation location,
807 GLsizei count,
808 GLboolean transpose,
809 const GLfloat *value)
810 {
811 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT3, program, location, count,
812 transpose);
813 }
814
ValidateProgramUniformMatrix4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)815 bool ValidateProgramUniformMatrix4fvBase(const Context *context,
816 ShaderProgramID program,
817 UniformLocation location,
818 GLsizei count,
819 GLboolean transpose,
820 const GLfloat *value)
821 {
822 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT4, program, location, count,
823 transpose);
824 }
825
ValidateProgramUniformMatrix2x3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)826 bool ValidateProgramUniformMatrix2x3fvBase(const Context *context,
827 ShaderProgramID program,
828 UniformLocation location,
829 GLsizei count,
830 GLboolean transpose,
831 const GLfloat *value)
832 {
833 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT2x3, program, location, count,
834 transpose);
835 }
836
ValidateProgramUniformMatrix3x2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)837 bool ValidateProgramUniformMatrix3x2fvBase(const Context *context,
838 ShaderProgramID program,
839 UniformLocation location,
840 GLsizei count,
841 GLboolean transpose,
842 const GLfloat *value)
843 {
844 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT3x2, program, location, count,
845 transpose);
846 }
847
ValidateProgramUniformMatrix2x4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)848 bool ValidateProgramUniformMatrix2x4fvBase(const Context *context,
849 ShaderProgramID program,
850 UniformLocation location,
851 GLsizei count,
852 GLboolean transpose,
853 const GLfloat *value)
854 {
855 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT2x4, program, location, count,
856 transpose);
857 }
858
ValidateProgramUniformMatrix4x2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)859 bool ValidateProgramUniformMatrix4x2fvBase(const Context *context,
860 ShaderProgramID program,
861 UniformLocation location,
862 GLsizei count,
863 GLboolean transpose,
864 const GLfloat *value)
865 {
866 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT4x2, program, location, count,
867 transpose);
868 }
869
ValidateProgramUniformMatrix3x4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)870 bool ValidateProgramUniformMatrix3x4fvBase(const Context *context,
871 ShaderProgramID program,
872 UniformLocation location,
873 GLsizei count,
874 GLboolean transpose,
875 const GLfloat *value)
876 {
877 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT3x4, program, location, count,
878 transpose);
879 }
880
ValidateProgramUniformMatrix4x3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)881 bool ValidateProgramUniformMatrix4x3fvBase(const Context *context,
882 ShaderProgramID program,
883 UniformLocation location,
884 GLsizei count,
885 GLboolean transpose,
886 const GLfloat *value)
887 {
888 return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT4x3, program, location, count,
889 transpose);
890 }
891
ValidateGetTexLevelParameterfv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLfloat * params)892 bool ValidateGetTexLevelParameterfv(const Context *context,
893 TextureTarget target,
894 GLint level,
895 GLenum pname,
896 const GLfloat *params)
897 {
898 if (context->getClientVersion() < ES_3_1)
899 {
900 context->validationError(GL_INVALID_OPERATION, kES31Required);
901 return false;
902 }
903
904 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
905 }
906
ValidateGetTexLevelParameterfvRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)907 bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
908 TextureTarget target,
909 GLint level,
910 GLenum pname,
911 GLsizei bufSize,
912 const GLsizei *length,
913 const GLfloat *params)
914 {
915 UNIMPLEMENTED();
916 return false;
917 }
918
ValidateGetTexLevelParameteriv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLint * params)919 bool ValidateGetTexLevelParameteriv(const Context *context,
920 TextureTarget target,
921 GLint level,
922 GLenum pname,
923 const GLint *params)
924 {
925 if (context->getClientVersion() < ES_3_1)
926 {
927 context->validationError(GL_INVALID_OPERATION, kES31Required);
928 return false;
929 }
930
931 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
932 }
933
ValidateGetTexLevelParameterivRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)934 bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
935 TextureTarget target,
936 GLint level,
937 GLenum pname,
938 GLsizei bufSize,
939 const GLsizei *length,
940 const GLint *params)
941 {
942 UNIMPLEMENTED();
943 return false;
944 }
945
ValidateTexStorage2DMultisample(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations)946 bool ValidateTexStorage2DMultisample(const Context *context,
947 TextureType target,
948 GLsizei samples,
949 GLenum internalFormat,
950 GLsizei width,
951 GLsizei height,
952 GLboolean fixedSampleLocations)
953 {
954 if (context->getClientVersion() < ES_3_1)
955 {
956 context->validationError(GL_INVALID_OPERATION, kES31Required);
957 return false;
958 }
959
960 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
961 height);
962 }
963
ValidateTexStorageMem2DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)964 bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
965 TextureType target,
966 GLsizei samples,
967 GLenum internalFormat,
968 GLsizei width,
969 GLsizei height,
970 GLboolean fixedSampleLocations,
971 MemoryObjectID memory,
972 GLuint64 offset)
973 {
974 if (!context->getExtensions().memoryObject)
975 {
976 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
977 return false;
978 }
979
980 UNIMPLEMENTED();
981 return false;
982 }
983
ValidateGetMultisamplefv(const Context * context,GLenum pname,GLuint index,const GLfloat * val)984 bool ValidateGetMultisamplefv(const Context *context,
985 GLenum pname,
986 GLuint index,
987 const GLfloat *val)
988 {
989 if (context->getClientVersion() < ES_3_1)
990 {
991 context->validationError(GL_INVALID_OPERATION, kES31Required);
992 return false;
993 }
994
995 return ValidateGetMultisamplefvBase(context, pname, index, val);
996 }
997
ValidateGetMultisamplefvRobustANGLE(const Context * context,GLenum pname,GLuint index,GLsizei bufSize,const GLsizei * length,const GLfloat * val)998 bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
999 GLenum pname,
1000 GLuint index,
1001 GLsizei bufSize,
1002 const GLsizei *length,
1003 const GLfloat *val)
1004 {
1005 UNIMPLEMENTED();
1006 return false;
1007 }
1008
ValidateFramebufferParameteri(const Context * context,GLenum target,GLenum pname,GLint param)1009 bool ValidateFramebufferParameteri(const Context *context, GLenum target, GLenum pname, GLint param)
1010 {
1011 if (context->getClientVersion() < ES_3_1)
1012 {
1013 context->validationError(GL_INVALID_OPERATION, kES31Required);
1014 return false;
1015 }
1016
1017 if (!ValidFramebufferTarget(context, target))
1018 {
1019 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1020 return false;
1021 }
1022
1023 switch (pname)
1024 {
1025 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1026 {
1027 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1028 if (param < 0 || param > maxWidth)
1029 {
1030 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferWidth);
1031 return false;
1032 }
1033 break;
1034 }
1035 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1036 {
1037 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1038 if (param < 0 || param > maxHeight)
1039 {
1040 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferHeight);
1041 return false;
1042 }
1043 break;
1044 }
1045 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1046 {
1047 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1048 if (param < 0 || param > maxSamples)
1049 {
1050 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferSamples);
1051 return false;
1052 }
1053 break;
1054 }
1055 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1056 {
1057 break;
1058 }
1059 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1060 {
1061 if (!context->getExtensions().geometryShaderAny() &&
1062 context->getClientVersion() < ES_3_2)
1063 {
1064 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1065 return false;
1066 }
1067 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1068 if (param < 0 || param > maxLayers)
1069 {
1070 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferLayer);
1071 return false;
1072 }
1073 break;
1074 }
1075 default:
1076 {
1077 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1078 return false;
1079 }
1080 }
1081
1082 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1083 ASSERT(framebuffer);
1084 if (framebuffer->isDefault())
1085 {
1086 context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1087 return false;
1088 }
1089 return true;
1090 }
1091
ValidateGetFramebufferParameteriv(const Context * context,GLenum target,GLenum pname,const GLint * params)1092 bool ValidateGetFramebufferParameteriv(const Context *context,
1093 GLenum target,
1094 GLenum pname,
1095 const GLint *params)
1096 {
1097 if (context->getClientVersion() < ES_3_1)
1098 {
1099 context->validationError(GL_INVALID_OPERATION, kES31Required);
1100 return false;
1101 }
1102
1103 if (!ValidFramebufferTarget(context, target))
1104 {
1105 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1106 return false;
1107 }
1108
1109 switch (pname)
1110 {
1111 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1112 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1113 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1114 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1115 break;
1116 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1117 if (!context->getExtensions().geometryShaderAny() &&
1118 context->getClientVersion() < ES_3_2)
1119 {
1120 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1121 return false;
1122 }
1123 break;
1124 default:
1125 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1126 return false;
1127 }
1128
1129 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1130 ASSERT(framebuffer);
1131
1132 if (framebuffer->isDefault())
1133 {
1134 context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1135 return false;
1136 }
1137 return true;
1138 }
1139
ValidateGetFramebufferParameterivRobustANGLE(const Context * context,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1140 bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
1141 GLenum target,
1142 GLenum pname,
1143 GLsizei bufSize,
1144 const GLsizei *length,
1145 const GLint *params)
1146 {
1147 UNIMPLEMENTED();
1148 return false;
1149 }
1150
ValidateGetProgramResourceIndex(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1151 bool ValidateGetProgramResourceIndex(const Context *context,
1152 ShaderProgramID program,
1153 GLenum programInterface,
1154 const GLchar *name)
1155 {
1156 if (context->getClientVersion() < ES_3_1)
1157 {
1158 context->validationError(GL_INVALID_OPERATION, kES31Required);
1159 return false;
1160 }
1161
1162 Program *programObject = GetValidProgram(context, program);
1163 if (programObject == nullptr)
1164 {
1165 return false;
1166 }
1167
1168 if (!ValidateNamedProgramInterface(programInterface))
1169 {
1170 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1171 return false;
1172 }
1173
1174 return true;
1175 }
1176
ValidateBindVertexBuffer(const Context * context,GLuint bindingIndex,BufferID buffer,GLintptr offset,GLsizei stride)1177 bool ValidateBindVertexBuffer(const Context *context,
1178 GLuint bindingIndex,
1179 BufferID buffer,
1180 GLintptr offset,
1181 GLsizei stride)
1182 {
1183 if (context->getClientVersion() < ES_3_1)
1184 {
1185 context->validationError(GL_INVALID_OPERATION, kES31Required);
1186 return false;
1187 }
1188
1189 if (!context->isBufferGenerated(buffer))
1190 {
1191 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1192 return false;
1193 }
1194
1195 const Caps &caps = context->getCaps();
1196 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1197 {
1198 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1199 return false;
1200 }
1201
1202 if (offset < 0)
1203 {
1204 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1205 return false;
1206 }
1207
1208 if (stride < 0 || stride > caps.maxVertexAttribStride)
1209 {
1210 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
1211 return false;
1212 }
1213
1214 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1215 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1216 if (context->getState().getVertexArrayId().value == 0)
1217 {
1218 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1219 return false;
1220 }
1221
1222 return true;
1223 }
1224
ValidateVertexBindingDivisor(const Context * context,GLuint bindingIndex,GLuint divisor)1225 bool ValidateVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
1226 {
1227 if (context->getClientVersion() < ES_3_1)
1228 {
1229 context->validationError(GL_INVALID_OPERATION, kES31Required);
1230 return false;
1231 }
1232
1233 const Caps &caps = context->getCaps();
1234 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1235 {
1236 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1237 return false;
1238 }
1239
1240 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1241 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1242 if (context->getState().getVertexArrayId().value == 0)
1243 {
1244 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1245 return false;
1246 }
1247
1248 return true;
1249 }
1250
ValidateVertexAttribFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeoffset)1251 bool ValidateVertexAttribFormat(const Context *context,
1252 GLuint attribindex,
1253 GLint size,
1254 VertexAttribType type,
1255 GLboolean normalized,
1256 GLuint relativeoffset)
1257 {
1258 if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1259 {
1260 return false;
1261 }
1262
1263 return ValidateFloatVertexFormat(context, attribindex, size, type);
1264 }
1265
ValidateVertexAttribIFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLuint relativeoffset)1266 bool ValidateVertexAttribIFormat(const Context *context,
1267 GLuint attribindex,
1268 GLint size,
1269 VertexAttribType type,
1270 GLuint relativeoffset)
1271 {
1272 if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1273 {
1274 return false;
1275 }
1276
1277 return ValidateIntegerVertexFormat(context, attribindex, size, type);
1278 }
1279
ValidateVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)1280 bool ValidateVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
1281 {
1282 if (context->getClientVersion() < ES_3_1)
1283 {
1284 context->validationError(GL_INVALID_OPERATION, kES31Required);
1285 return false;
1286 }
1287
1288 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1289 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1290 if (context->getState().getVertexArrayId().value == 0)
1291 {
1292 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1293 return false;
1294 }
1295
1296 const Caps &caps = context->getCaps();
1297 if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
1298 {
1299 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
1300 return false;
1301 }
1302
1303 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1304 {
1305 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1306 return false;
1307 }
1308
1309 return true;
1310 }
1311
ValidateGetProgramResourceName(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,const GLsizei * length,const GLchar * name)1312 bool ValidateGetProgramResourceName(const Context *context,
1313 ShaderProgramID program,
1314 GLenum programInterface,
1315 GLuint index,
1316 GLsizei bufSize,
1317 const GLsizei *length,
1318 const GLchar *name)
1319 {
1320 if (context->getClientVersion() < ES_3_1)
1321 {
1322 context->validationError(GL_INVALID_OPERATION, kES31Required);
1323 return false;
1324 }
1325
1326 Program *programObject = GetValidProgram(context, program);
1327 if (programObject == nullptr)
1328 {
1329 return false;
1330 }
1331
1332 if (!ValidateNamedProgramInterface(programInterface))
1333 {
1334 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1335 return false;
1336 }
1337
1338 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1339 {
1340 context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1341 return false;
1342 }
1343
1344 if (bufSize < 0)
1345 {
1346 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1347 return false;
1348 }
1349
1350 return true;
1351 }
1352
ValidateDispatchCompute(const Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)1353 bool ValidateDispatchCompute(const Context *context,
1354 GLuint numGroupsX,
1355 GLuint numGroupsY,
1356 GLuint numGroupsZ)
1357 {
1358 if (context->getClientVersion() < ES_3_1)
1359 {
1360 context->validationError(GL_INVALID_OPERATION, kES31Required);
1361 return false;
1362 }
1363
1364 const State &state = context->getState();
1365 const ProgramExecutable *executable = state.getProgramExecutable();
1366
1367 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1368 {
1369 context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1370 return false;
1371 }
1372
1373 const Caps &caps = context->getCaps();
1374 if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
1375 {
1376 context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
1377 return false;
1378 }
1379 if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
1380 {
1381 context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
1382 return false;
1383 }
1384 if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
1385 {
1386 context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
1387 return false;
1388 }
1389
1390 return true;
1391 }
1392
ValidateDispatchComputeIndirect(const Context * context,GLintptr indirect)1393 bool ValidateDispatchComputeIndirect(const Context *context, GLintptr indirect)
1394 {
1395 if (context->getClientVersion() < ES_3_1)
1396 {
1397 context->validationError(GL_INVALID_OPERATION, kES31Required);
1398 return false;
1399 }
1400
1401 const State &state = context->getState();
1402 const ProgramExecutable *executable = state.getProgramExecutable();
1403
1404 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1405 {
1406 context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1407 return false;
1408 }
1409
1410 if (indirect < 0)
1411 {
1412 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1413 return false;
1414 }
1415
1416 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1417 {
1418 context->validationError(GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
1419 return false;
1420 }
1421
1422 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
1423 if (!dispatchIndirectBuffer)
1424 {
1425 context->validationError(GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
1426 return false;
1427 }
1428
1429 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1430 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1431 if (!checkedSum.IsValid() ||
1432 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1433 {
1434 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
1435 return false;
1436 }
1437
1438 return true;
1439 }
1440
ValidateBindImageTexture(const Context * context,GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1441 bool ValidateBindImageTexture(const Context *context,
1442 GLuint unit,
1443 TextureID texture,
1444 GLint level,
1445 GLboolean layered,
1446 GLint layer,
1447 GLenum access,
1448 GLenum format)
1449 {
1450 if (context->getClientVersion() < ES_3_1)
1451 {
1452 context->validationError(GL_INVALID_OPERATION, kES31Required);
1453 return false;
1454 }
1455
1456 GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
1457 if (unit >= maxImageUnits)
1458 {
1459 context->validationError(GL_INVALID_VALUE, kExceedsMaxImageUnits);
1460 return false;
1461 }
1462
1463 if (level < 0)
1464 {
1465 context->validationError(GL_INVALID_VALUE, kNegativeLevel);
1466 return false;
1467 }
1468
1469 if (layer < 0)
1470 {
1471 context->validationError(GL_INVALID_VALUE, kNegativeLayer);
1472 return false;
1473 }
1474
1475 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1476 {
1477 context->validationError(GL_INVALID_ENUM, kInvalidImageAccess);
1478 return false;
1479 }
1480
1481 switch (format)
1482 {
1483 case GL_RGBA32F:
1484 case GL_RGBA16F:
1485 case GL_R32F:
1486 case GL_RGBA32UI:
1487 case GL_RGBA16UI:
1488 case GL_RGBA8UI:
1489 case GL_R32UI:
1490 case GL_RGBA32I:
1491 case GL_RGBA16I:
1492 case GL_RGBA8I:
1493 case GL_R32I:
1494 case GL_RGBA8:
1495 case GL_RGBA8_SNORM:
1496 break;
1497 default:
1498 context->validationError(GL_INVALID_VALUE, kInvalidImageFormat);
1499 return false;
1500 }
1501
1502 if (texture.value != 0)
1503 {
1504 Texture *tex = context->getTexture(texture);
1505
1506 if (tex == nullptr)
1507 {
1508 context->validationError(GL_INVALID_VALUE, kMissingTextureName);
1509 return false;
1510 }
1511
1512 if (!tex->getImmutableFormat())
1513 {
1514 context->validationError(GL_INVALID_OPERATION, kTextureIsNotImmutable);
1515 return false;
1516 }
1517 }
1518
1519 return true;
1520 }
1521
ValidateGetProgramResourceLocation(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1522 bool ValidateGetProgramResourceLocation(const Context *context,
1523 ShaderProgramID program,
1524 GLenum programInterface,
1525 const GLchar *name)
1526 {
1527 if (context->getClientVersion() < ES_3_1)
1528 {
1529 context->validationError(GL_INVALID_OPERATION, kES31Required);
1530 return false;
1531 }
1532
1533 Program *programObject = GetValidProgram(context, program);
1534 if (programObject == nullptr)
1535 {
1536 return false;
1537 }
1538
1539 if (!programObject->isLinked())
1540 {
1541 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1542 return false;
1543 }
1544
1545 if (!ValidateLocationProgramInterface(programInterface))
1546 {
1547 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1548 return false;
1549 }
1550 return true;
1551 }
1552
ValidateGetProgramResourceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,const GLsizei * length,const GLint * params)1553 bool ValidateGetProgramResourceiv(const Context *context,
1554 ShaderProgramID program,
1555 GLenum programInterface,
1556 GLuint index,
1557 GLsizei propCount,
1558 const GLenum *props,
1559 GLsizei bufSize,
1560 const GLsizei *length,
1561 const GLint *params)
1562 {
1563 if (context->getClientVersion() < ES_3_1)
1564 {
1565 context->validationError(GL_INVALID_OPERATION, kES31Required);
1566 return false;
1567 }
1568
1569 Program *programObject = GetValidProgram(context, program);
1570 if (programObject == nullptr)
1571 {
1572 return false;
1573 }
1574 if (!ValidateProgramInterface(programInterface))
1575 {
1576 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1577 return false;
1578 }
1579 if (propCount <= 0)
1580 {
1581 context->validationError(GL_INVALID_VALUE, kInvalidPropCount);
1582 return false;
1583 }
1584 if (bufSize < 0)
1585 {
1586 context->validationError(GL_INVALID_VALUE, kNegativeBufSize);
1587 return false;
1588 }
1589 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1590 {
1591 context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1592 return false;
1593 }
1594 for (GLsizei i = 0; i < propCount; i++)
1595 {
1596 if (!ValidateProgramResourceProperty(context, props[i]))
1597 {
1598 context->validationError(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1599 return false;
1600 }
1601 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1602 {
1603 context->validationError(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
1604 return false;
1605 }
1606 }
1607 return true;
1608 }
1609
ValidateGetProgramInterfaceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1610 bool ValidateGetProgramInterfaceiv(const Context *context,
1611 ShaderProgramID program,
1612 GLenum programInterface,
1613 GLenum pname,
1614 const GLint *params)
1615 {
1616 if (context->getClientVersion() < ES_3_1)
1617 {
1618 context->validationError(GL_INVALID_OPERATION, kES31Required);
1619 return false;
1620 }
1621
1622 Program *programObject = GetValidProgram(context, program);
1623 if (programObject == nullptr)
1624 {
1625 return false;
1626 }
1627
1628 if (!ValidateProgramInterface(programInterface))
1629 {
1630 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1631 return false;
1632 }
1633
1634 switch (pname)
1635 {
1636 case GL_ACTIVE_RESOURCES:
1637 case GL_MAX_NAME_LENGTH:
1638 case GL_MAX_NUM_ACTIVE_VARIABLES:
1639 break;
1640
1641 default:
1642 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1643 return false;
1644 }
1645
1646 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1647 {
1648 context->validationError(GL_INVALID_OPERATION, kAtomicCounterResourceName);
1649 return false;
1650 }
1651
1652 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1653 {
1654 switch (programInterface)
1655 {
1656 case GL_ATOMIC_COUNTER_BUFFER:
1657 case GL_SHADER_STORAGE_BLOCK:
1658 case GL_UNIFORM_BLOCK:
1659 break;
1660
1661 default:
1662 context->validationError(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
1663 return false;
1664 }
1665 }
1666
1667 return true;
1668 }
1669
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1670 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1671 ShaderProgramID program,
1672 GLenum programInterface,
1673 GLenum pname,
1674 GLsizei bufSize,
1675 const GLsizei *length,
1676 const GLint *params)
1677 {
1678 UNIMPLEMENTED();
1679 return false;
1680 }
1681
ValidateGenProgramPipelinesBase(const Context * context,GLsizei n,const ProgramPipelineID * pipelines)1682 bool ValidateGenProgramPipelinesBase(const Context *context,
1683 GLsizei n,
1684 const ProgramPipelineID *pipelines)
1685 {
1686 return ValidateGenOrDelete(context, n);
1687 }
1688
ValidateDeleteProgramPipelinesBase(const Context * context,GLsizei n,const ProgramPipelineID * pipelines)1689 bool ValidateDeleteProgramPipelinesBase(const Context *context,
1690 GLsizei n,
1691 const ProgramPipelineID *pipelines)
1692 {
1693 return ValidateGenOrDelete(context, n);
1694 }
1695
ValidateBindProgramPipelineBase(const Context * context,ProgramPipelineID pipeline)1696 bool ValidateBindProgramPipelineBase(const Context *context, ProgramPipelineID pipeline)
1697 {
1698 if (!context->isProgramPipelineGenerated({pipeline}))
1699 {
1700 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1701 return false;
1702 }
1703
1704 return true;
1705 }
1706
ValidateIsProgramPipelineBase(const Context * context,ProgramPipelineID pipeline)1707 bool ValidateIsProgramPipelineBase(const Context *context, ProgramPipelineID pipeline)
1708 {
1709 return true;
1710 }
1711
ValidateUseProgramStagesBase(const Context * context,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1712 bool ValidateUseProgramStagesBase(const Context *context,
1713 ProgramPipelineID pipeline,
1714 GLbitfield stages,
1715 ShaderProgramID programId)
1716 {
1717 // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
1718 // not the reserved value GL_ALL_SHADER_BITS.
1719 GLbitfield knownShaderBits =
1720 GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1721
1722 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
1723 {
1724 knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
1725 }
1726
1727 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT)
1728 {
1729 knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
1730 knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
1731 }
1732
1733 if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1734 {
1735 context->validationError(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1736 return false;
1737 }
1738
1739 // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1740 // to glGenProgramPipelines or if such a name has been deleted by a call to
1741 // glDeleteProgramPipelines.
1742 if (!context->isProgramPipelineGenerated({pipeline}))
1743 {
1744 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1745 return false;
1746 }
1747
1748 // If program is zero, or refers to a program object with no valid shader executable for a given
1749 // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1750 // shader stages.
1751 if (programId.value == 0)
1752 {
1753 return true;
1754 }
1755
1756 Program *program = context->getProgramNoResolveLink(programId);
1757 if (!program)
1758 {
1759 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1760 return false;
1761 }
1762
1763 // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1764 // with its GL_PROGRAM_SEPARABLE status set.
1765 // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1766 // glDetachShader() was not called.
1767 program->resolveLink(context);
1768 if (!program->isSeparable())
1769 {
1770 context->validationError(GL_INVALID_OPERATION, kProgramNotSeparable);
1771 return false;
1772 }
1773
1774 // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1775 // successfully linked.
1776 if (!program->isLinked())
1777 {
1778 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1779 return false;
1780 }
1781
1782 return true;
1783 }
1784
ValidateActiveShaderProgramBase(const Context * context,ProgramPipelineID pipeline,ShaderProgramID programId)1785 bool ValidateActiveShaderProgramBase(const Context *context,
1786 ProgramPipelineID pipeline,
1787 ShaderProgramID programId)
1788 {
1789 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1790 // call to GenProgramPipelines or if such a name has since been deleted by
1791 // DeleteProgramPipelines.
1792 if (!context->isProgramPipelineGenerated({pipeline}))
1793 {
1794 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1795 return false;
1796 }
1797
1798 // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1799 // program or shader object.
1800 if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1801 {
1802 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1803 return false;
1804 }
1805
1806 // An INVALID_OPERATION error is generated if program is the name of a shader object.
1807 if (context->isShader(programId))
1808 {
1809 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
1810 return false;
1811 }
1812
1813 // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1814 // was last linked unsuccessfully. The active program is not modified.
1815 Program *program = context->getProgramNoResolveLink(programId);
1816 if ((programId.value != 0) && !program->isLinked())
1817 {
1818 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1819 return false;
1820 }
1821
1822 return true;
1823 }
1824
ValidateCreateShaderProgramvBase(const Context * context,ShaderType type,GLsizei count,const GLchar * const * strings)1825 bool ValidateCreateShaderProgramvBase(const Context *context,
1826 ShaderType type,
1827 GLsizei count,
1828 const GLchar *const *strings)
1829 {
1830 switch (type)
1831 {
1832 case ShaderType::InvalidEnum:
1833 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1834 return false;
1835 case ShaderType::Vertex:
1836 case ShaderType::Fragment:
1837 case ShaderType::Compute:
1838 break;
1839 case ShaderType::Geometry:
1840 if (!context->getExtensions().geometryShaderAny() &&
1841 context->getClientVersion() < ES_3_2)
1842 {
1843 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1844 return false;
1845 }
1846 break;
1847 case ShaderType::TessControl:
1848 case ShaderType::TessEvaluation:
1849 if (!context->getExtensions().tessellationShaderEXT &&
1850 context->getClientVersion() < ES_3_2)
1851 {
1852 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1853 return false;
1854 }
1855 break;
1856 default:
1857 UNREACHABLE();
1858 }
1859
1860 // GL_INVALID_VALUE is generated if count is negative.
1861 if (count < 0)
1862 {
1863 context->validationError(GL_INVALID_VALUE, kNegativeCount);
1864 return false;
1865 }
1866
1867 return true;
1868 }
1869
ValidateCreateShaderProgramvBase(const Context * context,ShaderType type,GLsizei count,const GLchar ** strings)1870 bool ValidateCreateShaderProgramvBase(const Context *context,
1871 ShaderType type,
1872 GLsizei count,
1873 const GLchar **strings)
1874 {
1875 const GLchar *const *tmpStrings = strings;
1876 return ValidateCreateShaderProgramvBase(context, type, count, tmpStrings);
1877 }
1878
ValidateGetProgramPipelineivBase(const Context * context,ProgramPipelineID pipeline,GLenum pname,const GLint * params)1879 bool ValidateGetProgramPipelineivBase(const Context *context,
1880 ProgramPipelineID pipeline,
1881 GLenum pname,
1882 const GLint *params)
1883 {
1884 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1885 // call to GenProgramPipelines or if such a name has since been deleted by
1886 // DeleteProgramPipelines.
1887 if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
1888 {
1889 context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1890 return false;
1891 }
1892
1893 // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
1894 // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
1895 // table 7.1.
1896 switch (pname)
1897 {
1898 case GL_ACTIVE_PROGRAM:
1899 case GL_INFO_LOG_LENGTH:
1900 case GL_VALIDATE_STATUS:
1901 case GL_VERTEX_SHADER:
1902 case GL_FRAGMENT_SHADER:
1903 case GL_COMPUTE_SHADER:
1904 break;
1905 case GL_GEOMETRY_SHADER:
1906 return context->getExtensions().geometryShaderAny() ||
1907 context->getClientVersion() >= ES_3_2;
1908 case GL_TESS_CONTROL_SHADER:
1909 case GL_TESS_EVALUATION_SHADER:
1910 return context->getExtensions().tessellationShaderEXT ||
1911 context->getClientVersion() >= ES_3_2;
1912
1913 default:
1914 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1915 return false;
1916 }
1917
1918 return true;
1919 }
1920
ValidateValidateProgramPipelineBase(const Context * context,ProgramPipelineID pipeline)1921 bool ValidateValidateProgramPipelineBase(const Context *context, ProgramPipelineID pipeline)
1922 {
1923 if (pipeline.value == 0)
1924 {
1925 return false;
1926 }
1927
1928 if (!context->isProgramPipelineGenerated(pipeline))
1929 {
1930 context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1931 return false;
1932 }
1933
1934 return true;
1935 }
1936
ValidateGetProgramPipelineInfoLogBase(const Context * context,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)1937 bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
1938 ProgramPipelineID pipeline,
1939 GLsizei bufSize,
1940 const GLsizei *length,
1941 const GLchar *infoLog)
1942 {
1943 if (bufSize < 0)
1944 {
1945 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1946 return false;
1947 }
1948
1949 if (!context->isProgramPipelineGenerated(pipeline))
1950 {
1951 context->validationError(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
1952 return false;
1953 }
1954
1955 return true;
1956 }
1957
ValidateActiveShaderProgram(const Context * context,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)1958 bool ValidateActiveShaderProgram(const Context *context,
1959 ProgramPipelineID pipelinePacked,
1960 ShaderProgramID programPacked)
1961 {
1962 if (context->getClientVersion() < ES_3_1)
1963 {
1964 context->validationError(GL_INVALID_OPERATION, kES31Required);
1965 return false;
1966 }
1967
1968 return ValidateActiveShaderProgramBase(context, pipelinePacked, programPacked);
1969 }
1970
ValidateBindProgramPipeline(const Context * context,ProgramPipelineID pipelinePacked)1971 bool ValidateBindProgramPipeline(const Context *context, ProgramPipelineID pipelinePacked)
1972 {
1973 if (context->getClientVersion() < ES_3_1)
1974 {
1975 context->validationError(GL_INVALID_OPERATION, kES31Required);
1976 return false;
1977 }
1978
1979 return ValidateBindProgramPipelineBase(context, pipelinePacked);
1980 }
1981
ValidateCreateShaderProgramv(const Context * context,ShaderType typePacked,GLsizei count,const GLchar * const * strings)1982 bool ValidateCreateShaderProgramv(const Context *context,
1983 ShaderType typePacked,
1984 GLsizei count,
1985 const GLchar *const *strings)
1986 {
1987 if (context->getClientVersion() < ES_3_1)
1988 {
1989 context->validationError(GL_INVALID_OPERATION, kES31Required);
1990 return false;
1991 }
1992
1993 return ValidateCreateShaderProgramvBase(context, typePacked, count, strings);
1994 }
1995
ValidateDeleteProgramPipelines(const Context * context,GLsizei n,const ProgramPipelineID * pipelinesPacked)1996 bool ValidateDeleteProgramPipelines(const Context *context,
1997 GLsizei n,
1998 const ProgramPipelineID *pipelinesPacked)
1999 {
2000 if (context->getClientVersion() < ES_3_1)
2001 {
2002 context->validationError(GL_INVALID_OPERATION, kES31Required);
2003 return false;
2004 }
2005
2006 return ValidateDeleteProgramPipelinesBase(context, n, pipelinesPacked);
2007 }
2008
ValidateGenProgramPipelines(const Context * context,GLsizei n,const ProgramPipelineID * pipelinesPacked)2009 bool ValidateGenProgramPipelines(const Context *context,
2010 GLsizei n,
2011 const ProgramPipelineID *pipelinesPacked)
2012 {
2013 if (context->getClientVersion() < ES_3_1)
2014 {
2015 context->validationError(GL_INVALID_OPERATION, kES31Required);
2016 return false;
2017 }
2018
2019 return ValidateGenProgramPipelinesBase(context, n, pipelinesPacked);
2020 }
2021
ValidateGetProgramPipelineInfoLog(const Context * context,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)2022 bool ValidateGetProgramPipelineInfoLog(const Context *context,
2023 ProgramPipelineID pipelinePacked,
2024 GLsizei bufSize,
2025 const GLsizei *length,
2026 const GLchar *infoLog)
2027 {
2028 if (context->getClientVersion() < ES_3_1)
2029 {
2030 context->validationError(GL_INVALID_OPERATION, kES31Required);
2031 return false;
2032 }
2033
2034 return ValidateGetProgramPipelineInfoLogBase(context, pipelinePacked, bufSize, length, infoLog);
2035 }
2036
ValidateGetProgramPipelineiv(const Context * context,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)2037 bool ValidateGetProgramPipelineiv(const Context *context,
2038 ProgramPipelineID pipelinePacked,
2039 GLenum pname,
2040 const GLint *params)
2041 {
2042 if (context->getClientVersion() < ES_3_1)
2043 {
2044 context->validationError(GL_INVALID_OPERATION, kES31Required);
2045 return false;
2046 }
2047
2048 return ValidateGetProgramPipelineivBase(context, pipelinePacked, pname, params);
2049 }
2050
ValidateIsProgramPipeline(const Context * context,ProgramPipelineID pipelinePacked)2051 bool ValidateIsProgramPipeline(const Context *context, ProgramPipelineID pipelinePacked)
2052 {
2053 if (context->getClientVersion() < ES_3_1)
2054 {
2055 context->validationError(GL_INVALID_OPERATION, kES31Required);
2056 return false;
2057 }
2058
2059 return ValidateIsProgramPipelineBase(context, pipelinePacked);
2060 }
2061
ValidateProgramUniform1f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)2062 bool ValidateProgramUniform1f(const Context *context,
2063 ShaderProgramID programPacked,
2064 UniformLocation locationPacked,
2065 GLfloat v0)
2066 {
2067 if (context->getClientVersion() < ES_3_1)
2068 {
2069 context->validationError(GL_INVALID_OPERATION, kES31Required);
2070 return false;
2071 }
2072
2073 return ValidateProgramUniform1fBase(context, programPacked, locationPacked, v0);
2074 }
2075
ValidateProgramUniform1fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2076 bool ValidateProgramUniform1fv(const Context *context,
2077 ShaderProgramID programPacked,
2078 UniformLocation locationPacked,
2079 GLsizei count,
2080 const GLfloat *value)
2081 {
2082 if (context->getClientVersion() < ES_3_1)
2083 {
2084 context->validationError(GL_INVALID_OPERATION, kES31Required);
2085 return false;
2086 }
2087
2088 return ValidateProgramUniform1fvBase(context, programPacked, locationPacked, count, value);
2089 }
2090
ValidateProgramUniform1i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)2091 bool ValidateProgramUniform1i(const Context *context,
2092 ShaderProgramID programPacked,
2093 UniformLocation locationPacked,
2094 GLint v0)
2095 {
2096 if (context->getClientVersion() < ES_3_1)
2097 {
2098 context->validationError(GL_INVALID_OPERATION, kES31Required);
2099 return false;
2100 }
2101
2102 return ValidateProgramUniform1iBase(context, programPacked, locationPacked, v0);
2103 }
2104
ValidateProgramUniform1iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2105 bool ValidateProgramUniform1iv(const Context *context,
2106 ShaderProgramID programPacked,
2107 UniformLocation locationPacked,
2108 GLsizei count,
2109 const GLint *value)
2110 {
2111 if (context->getClientVersion() < ES_3_1)
2112 {
2113 context->validationError(GL_INVALID_OPERATION, kES31Required);
2114 return false;
2115 }
2116
2117 return ValidateProgramUniform1ivBase(context, programPacked, locationPacked, count, value);
2118 }
2119
ValidateProgramUniform1ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)2120 bool ValidateProgramUniform1ui(const Context *context,
2121 ShaderProgramID programPacked,
2122 UniformLocation locationPacked,
2123 GLuint v0)
2124 {
2125 if (context->getClientVersion() < ES_3_1)
2126 {
2127 context->validationError(GL_INVALID_OPERATION, kES31Required);
2128 return false;
2129 }
2130
2131 return ValidateProgramUniform1uiBase(context, programPacked, locationPacked, v0);
2132 }
2133
ValidateProgramUniform1uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2134 bool ValidateProgramUniform1uiv(const Context *context,
2135 ShaderProgramID programPacked,
2136 UniformLocation locationPacked,
2137 GLsizei count,
2138 const GLuint *value)
2139 {
2140 if (context->getClientVersion() < ES_3_1)
2141 {
2142 context->validationError(GL_INVALID_OPERATION, kES31Required);
2143 return false;
2144 }
2145
2146 return ValidateProgramUniform1uivBase(context, programPacked, locationPacked, count, value);
2147 }
2148
ValidateProgramUniform2f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)2149 bool ValidateProgramUniform2f(const Context *context,
2150 ShaderProgramID programPacked,
2151 UniformLocation locationPacked,
2152 GLfloat v0,
2153 GLfloat v1)
2154 {
2155 if (context->getClientVersion() < ES_3_1)
2156 {
2157 context->validationError(GL_INVALID_OPERATION, kES31Required);
2158 return false;
2159 }
2160
2161 return ValidateProgramUniform2fBase(context, programPacked, locationPacked, v0, v1);
2162 }
2163
ValidateProgramUniform2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2164 bool ValidateProgramUniform2fv(const Context *context,
2165 ShaderProgramID programPacked,
2166 UniformLocation locationPacked,
2167 GLsizei count,
2168 const GLfloat *value)
2169 {
2170 if (context->getClientVersion() < ES_3_1)
2171 {
2172 context->validationError(GL_INVALID_OPERATION, kES31Required);
2173 return false;
2174 }
2175
2176 return ValidateProgramUniform2fvBase(context, programPacked, locationPacked, count, value);
2177 }
2178
ValidateProgramUniform2i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)2179 bool ValidateProgramUniform2i(const Context *context,
2180 ShaderProgramID programPacked,
2181 UniformLocation locationPacked,
2182 GLint v0,
2183 GLint v1)
2184 {
2185 if (context->getClientVersion() < ES_3_1)
2186 {
2187 context->validationError(GL_INVALID_OPERATION, kES31Required);
2188 return false;
2189 }
2190
2191 return ValidateProgramUniform2iBase(context, programPacked, locationPacked, v0, v1);
2192 }
2193
ValidateProgramUniform2iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2194 bool ValidateProgramUniform2iv(const Context *context,
2195 ShaderProgramID programPacked,
2196 UniformLocation locationPacked,
2197 GLsizei count,
2198 const GLint *value)
2199 {
2200 if (context->getClientVersion() < ES_3_1)
2201 {
2202 context->validationError(GL_INVALID_OPERATION, kES31Required);
2203 return false;
2204 }
2205
2206 return ValidateProgramUniform2ivBase(context, programPacked, locationPacked, count, value);
2207 }
2208
ValidateProgramUniform2ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)2209 bool ValidateProgramUniform2ui(const Context *context,
2210 ShaderProgramID programPacked,
2211 UniformLocation locationPacked,
2212 GLuint v0,
2213 GLuint v1)
2214 {
2215 if (context->getClientVersion() < ES_3_1)
2216 {
2217 context->validationError(GL_INVALID_OPERATION, kES31Required);
2218 return false;
2219 }
2220
2221 return ValidateProgramUniform2uiBase(context, programPacked, locationPacked, v0, v1);
2222 }
2223
ValidateProgramUniform2uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2224 bool ValidateProgramUniform2uiv(const Context *context,
2225 ShaderProgramID programPacked,
2226 UniformLocation locationPacked,
2227 GLsizei count,
2228 const GLuint *value)
2229 {
2230 if (context->getClientVersion() < ES_3_1)
2231 {
2232 context->validationError(GL_INVALID_OPERATION, kES31Required);
2233 return false;
2234 }
2235
2236 return ValidateProgramUniform2uivBase(context, programPacked, locationPacked, count, value);
2237 }
2238
ValidateProgramUniform3f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)2239 bool ValidateProgramUniform3f(const Context *context,
2240 ShaderProgramID programPacked,
2241 UniformLocation locationPacked,
2242 GLfloat v0,
2243 GLfloat v1,
2244 GLfloat v2)
2245 {
2246 if (context->getClientVersion() < ES_3_1)
2247 {
2248 context->validationError(GL_INVALID_OPERATION, kES31Required);
2249 return false;
2250 }
2251
2252 return ValidateProgramUniform3fBase(context, programPacked, locationPacked, v0, v1, v2);
2253 }
2254
ValidateProgramUniform3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2255 bool ValidateProgramUniform3fv(const Context *context,
2256 ShaderProgramID programPacked,
2257 UniformLocation locationPacked,
2258 GLsizei count,
2259 const GLfloat *value)
2260 {
2261 if (context->getClientVersion() < ES_3_1)
2262 {
2263 context->validationError(GL_INVALID_OPERATION, kES31Required);
2264 return false;
2265 }
2266
2267 return ValidateProgramUniform3fvBase(context, programPacked, locationPacked, count, value);
2268 }
2269
ValidateProgramUniform3i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)2270 bool ValidateProgramUniform3i(const Context *context,
2271 ShaderProgramID programPacked,
2272 UniformLocation locationPacked,
2273 GLint v0,
2274 GLint v1,
2275 GLint v2)
2276 {
2277 if (context->getClientVersion() < ES_3_1)
2278 {
2279 context->validationError(GL_INVALID_OPERATION, kES31Required);
2280 return false;
2281 }
2282
2283 return ValidateProgramUniform3iBase(context, programPacked, locationPacked, v0, v1, v2);
2284 }
2285
ValidateProgramUniform3iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2286 bool ValidateProgramUniform3iv(const Context *context,
2287 ShaderProgramID programPacked,
2288 UniformLocation locationPacked,
2289 GLsizei count,
2290 const GLint *value)
2291 {
2292 if (context->getClientVersion() < ES_3_1)
2293 {
2294 context->validationError(GL_INVALID_OPERATION, kES31Required);
2295 return false;
2296 }
2297
2298 return ValidateProgramUniform3ivBase(context, programPacked, locationPacked, count, value);
2299 }
2300
ValidateProgramUniform3ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)2301 bool ValidateProgramUniform3ui(const Context *context,
2302 ShaderProgramID programPacked,
2303 UniformLocation locationPacked,
2304 GLuint v0,
2305 GLuint v1,
2306 GLuint v2)
2307 {
2308 if (context->getClientVersion() < ES_3_1)
2309 {
2310 context->validationError(GL_INVALID_OPERATION, kES31Required);
2311 return false;
2312 }
2313
2314 return ValidateProgramUniform3uiBase(context, programPacked, locationPacked, v0, v1, v2);
2315 }
2316
ValidateProgramUniform3uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2317 bool ValidateProgramUniform3uiv(const Context *context,
2318 ShaderProgramID programPacked,
2319 UniformLocation locationPacked,
2320 GLsizei count,
2321 const GLuint *value)
2322 {
2323 if (context->getClientVersion() < ES_3_1)
2324 {
2325 context->validationError(GL_INVALID_OPERATION, kES31Required);
2326 return false;
2327 }
2328
2329 return ValidateProgramUniform3uivBase(context, programPacked, locationPacked, count, value);
2330 }
2331
ValidateProgramUniform4f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)2332 bool ValidateProgramUniform4f(const Context *context,
2333 ShaderProgramID programPacked,
2334 UniformLocation locationPacked,
2335 GLfloat v0,
2336 GLfloat v1,
2337 GLfloat v2,
2338 GLfloat v3)
2339 {
2340 if (context->getClientVersion() < ES_3_1)
2341 {
2342 context->validationError(GL_INVALID_OPERATION, kES31Required);
2343 return false;
2344 }
2345
2346 return ValidateProgramUniform4fBase(context, programPacked, locationPacked, v0, v1, v2, v3);
2347 }
2348
ValidateProgramUniform4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2349 bool ValidateProgramUniform4fv(const Context *context,
2350 ShaderProgramID programPacked,
2351 UniformLocation locationPacked,
2352 GLsizei count,
2353 const GLfloat *value)
2354 {
2355 if (context->getClientVersion() < ES_3_1)
2356 {
2357 context->validationError(GL_INVALID_OPERATION, kES31Required);
2358 return false;
2359 }
2360
2361 return ValidateProgramUniform4fvBase(context, programPacked, locationPacked, count, value);
2362 }
2363
ValidateProgramUniform4i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)2364 bool ValidateProgramUniform4i(const Context *context,
2365 ShaderProgramID programPacked,
2366 UniformLocation locationPacked,
2367 GLint v0,
2368 GLint v1,
2369 GLint v2,
2370 GLint v3)
2371 {
2372 if (context->getClientVersion() < ES_3_1)
2373 {
2374 context->validationError(GL_INVALID_OPERATION, kES31Required);
2375 return false;
2376 }
2377
2378 return ValidateProgramUniform4iBase(context, programPacked, locationPacked, v0, v1, v2, v3);
2379 }
2380
ValidateProgramUniform4iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2381 bool ValidateProgramUniform4iv(const Context *context,
2382 ShaderProgramID programPacked,
2383 UniformLocation locationPacked,
2384 GLsizei count,
2385 const GLint *value)
2386 {
2387 if (context->getClientVersion() < ES_3_1)
2388 {
2389 context->validationError(GL_INVALID_OPERATION, kES31Required);
2390 return false;
2391 }
2392
2393 return ValidateProgramUniform4ivBase(context, programPacked, locationPacked, count, value);
2394 }
2395
ValidateProgramUniform4ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)2396 bool ValidateProgramUniform4ui(const Context *context,
2397 ShaderProgramID programPacked,
2398 UniformLocation locationPacked,
2399 GLuint v0,
2400 GLuint v1,
2401 GLuint v2,
2402 GLuint v3)
2403 {
2404 if (context->getClientVersion() < ES_3_1)
2405 {
2406 context->validationError(GL_INVALID_OPERATION, kES31Required);
2407 return false;
2408 }
2409
2410 return ValidateProgramUniform4uiBase(context, programPacked, locationPacked, v0, v1, v2, v3);
2411 }
2412
ValidateProgramUniform4uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2413 bool ValidateProgramUniform4uiv(const Context *context,
2414 ShaderProgramID programPacked,
2415 UniformLocation locationPacked,
2416 GLsizei count,
2417 const GLuint *value)
2418 {
2419 if (context->getClientVersion() < ES_3_1)
2420 {
2421 context->validationError(GL_INVALID_OPERATION, kES31Required);
2422 return false;
2423 }
2424
2425 return ValidateProgramUniform4uivBase(context, programPacked, locationPacked, count, value);
2426 }
2427
ValidateProgramUniformMatrix2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2428 bool ValidateProgramUniformMatrix2fv(const Context *context,
2429 ShaderProgramID programPacked,
2430 UniformLocation locationPacked,
2431 GLsizei count,
2432 GLboolean transpose,
2433 const GLfloat *value)
2434 {
2435 if (context->getClientVersion() < ES_3_1)
2436 {
2437 context->validationError(GL_INVALID_OPERATION, kES31Required);
2438 return false;
2439 }
2440
2441 return ValidateProgramUniformMatrix2fvBase(context, programPacked, locationPacked, count,
2442 transpose, value);
2443 }
2444
ValidateProgramUniformMatrix2x3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2445 bool ValidateProgramUniformMatrix2x3fv(const Context *context,
2446 ShaderProgramID programPacked,
2447 UniformLocation locationPacked,
2448 GLsizei count,
2449 GLboolean transpose,
2450 const GLfloat *value)
2451 {
2452 if (context->getClientVersion() < ES_3_1)
2453 {
2454 context->validationError(GL_INVALID_OPERATION, kES31Required);
2455 return false;
2456 }
2457
2458 return ValidateProgramUniformMatrix2x3fvBase(context, programPacked, locationPacked, count,
2459 transpose, value);
2460 }
2461
ValidateProgramUniformMatrix2x4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2462 bool ValidateProgramUniformMatrix2x4fv(const Context *context,
2463 ShaderProgramID programPacked,
2464 UniformLocation locationPacked,
2465 GLsizei count,
2466 GLboolean transpose,
2467 const GLfloat *value)
2468 {
2469 if (context->getClientVersion() < ES_3_1)
2470 {
2471 context->validationError(GL_INVALID_OPERATION, kES31Required);
2472 return false;
2473 }
2474
2475 return ValidateProgramUniformMatrix2x4fvBase(context, programPacked, locationPacked, count,
2476 transpose, value);
2477 }
2478
ValidateProgramUniformMatrix3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2479 bool ValidateProgramUniformMatrix3fv(const Context *context,
2480 ShaderProgramID programPacked,
2481 UniformLocation locationPacked,
2482 GLsizei count,
2483 GLboolean transpose,
2484 const GLfloat *value)
2485 {
2486 if (context->getClientVersion() < ES_3_1)
2487 {
2488 context->validationError(GL_INVALID_OPERATION, kES31Required);
2489 return false;
2490 }
2491
2492 return ValidateProgramUniformMatrix3fvBase(context, programPacked, locationPacked, count,
2493 transpose, value);
2494 }
2495
ValidateProgramUniformMatrix3x2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2496 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
2497 ShaderProgramID programPacked,
2498 UniformLocation locationPacked,
2499 GLsizei count,
2500 GLboolean transpose,
2501 const GLfloat *value)
2502 {
2503 if (context->getClientVersion() < ES_3_1)
2504 {
2505 context->validationError(GL_INVALID_OPERATION, kES31Required);
2506 return false;
2507 }
2508
2509 return ValidateProgramUniformMatrix3x2fvBase(context, programPacked, locationPacked, count,
2510 transpose, value);
2511 }
2512
ValidateProgramUniformMatrix3x4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2513 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
2514 ShaderProgramID programPacked,
2515 UniformLocation locationPacked,
2516 GLsizei count,
2517 GLboolean transpose,
2518 const GLfloat *value)
2519 {
2520 if (context->getClientVersion() < ES_3_1)
2521 {
2522 context->validationError(GL_INVALID_OPERATION, kES31Required);
2523 return false;
2524 }
2525
2526 return ValidateProgramUniformMatrix3x4fvBase(context, programPacked, locationPacked, count,
2527 transpose, value);
2528 }
2529
ValidateProgramUniformMatrix4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2530 bool ValidateProgramUniformMatrix4fv(const Context *context,
2531 ShaderProgramID programPacked,
2532 UniformLocation locationPacked,
2533 GLsizei count,
2534 GLboolean transpose,
2535 const GLfloat *value)
2536 {
2537 if (context->getClientVersion() < ES_3_1)
2538 {
2539 context->validationError(GL_INVALID_OPERATION, kES31Required);
2540 return false;
2541 }
2542
2543 return ValidateProgramUniformMatrix4fvBase(context, programPacked, locationPacked, count,
2544 transpose, value);
2545 }
2546
ValidateProgramUniformMatrix4x2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2547 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
2548 ShaderProgramID programPacked,
2549 UniformLocation locationPacked,
2550 GLsizei count,
2551 GLboolean transpose,
2552 const GLfloat *value)
2553 {
2554 if (context->getClientVersion() < ES_3_1)
2555 {
2556 context->validationError(GL_INVALID_OPERATION, kES31Required);
2557 return false;
2558 }
2559
2560 return ValidateProgramUniformMatrix4x2fvBase(context, programPacked, locationPacked, count,
2561 transpose, value);
2562 }
2563
ValidateProgramUniformMatrix4x3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2564 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
2565 ShaderProgramID programPacked,
2566 UniformLocation locationPacked,
2567 GLsizei count,
2568 GLboolean transpose,
2569 const GLfloat *value)
2570 {
2571 if (context->getClientVersion() < ES_3_1)
2572 {
2573 context->validationError(GL_INVALID_OPERATION, kES31Required);
2574 return false;
2575 }
2576
2577 return ValidateProgramUniformMatrix4x3fvBase(context, programPacked, locationPacked, count,
2578 transpose, value);
2579 }
2580
ValidateUseProgramStages(const Context * context,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)2581 bool ValidateUseProgramStages(const Context *context,
2582 ProgramPipelineID pipelinePacked,
2583 GLbitfield stages,
2584 ShaderProgramID programPacked)
2585 {
2586 if (context->getClientVersion() < ES_3_1)
2587 {
2588 context->validationError(GL_INVALID_OPERATION, kES31Required);
2589 return false;
2590 }
2591
2592 return ValidateUseProgramStagesBase(context, pipelinePacked, stages, programPacked);
2593 }
2594
ValidateValidateProgramPipeline(const Context * context,ProgramPipelineID pipelinePacked)2595 bool ValidateValidateProgramPipeline(const Context *context, ProgramPipelineID pipelinePacked)
2596 {
2597 if (context->getClientVersion() < ES_3_1)
2598 {
2599 context->validationError(GL_INVALID_OPERATION, kES31Required);
2600 return false;
2601 }
2602
2603 return ValidateValidateProgramPipelineBase(context, pipelinePacked);
2604 }
2605
ValidateMemoryBarrier(const Context * context,GLbitfield barriers)2606 bool ValidateMemoryBarrier(const Context *context, GLbitfield barriers)
2607 {
2608 if (context->getClientVersion() < ES_3_1)
2609 {
2610 context->validationError(GL_INVALID_OPERATION, kES31Required);
2611 return false;
2612 }
2613
2614 if (barriers == GL_ALL_BARRIER_BITS)
2615 {
2616 return true;
2617 }
2618
2619 GLbitfield supported_barrier_bits =
2620 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
2621 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
2622 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
2623 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
2624 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
2625
2626 if (context->getExtensions().bufferStorageEXT)
2627 {
2628 supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
2629 }
2630
2631 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2632 {
2633 context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2634 return false;
2635 }
2636
2637 return true;
2638 }
2639
ValidateMemoryBarrierByRegion(const Context * context,GLbitfield barriers)2640 bool ValidateMemoryBarrierByRegion(const Context *context, GLbitfield barriers)
2641 {
2642 if (context->getClientVersion() < ES_3_1)
2643 {
2644 context->validationError(GL_INVALID_OPERATION, kES31Required);
2645 return false;
2646 }
2647
2648 if (barriers == GL_ALL_BARRIER_BITS)
2649 {
2650 return true;
2651 }
2652
2653 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
2654 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
2655 GL_SHADER_STORAGE_BARRIER_BIT |
2656 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
2657 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2658 {
2659 context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2660 return false;
2661 }
2662
2663 return true;
2664 }
2665
ValidateSampleMaski(const Context * context,GLuint maskNumber,GLbitfield mask)2666 bool ValidateSampleMaski(const Context *context, GLuint maskNumber, GLbitfield mask)
2667 {
2668 if (context->getClientVersion() < ES_3_1)
2669 {
2670 context->validationError(GL_INVALID_OPERATION, kES31Required);
2671 return false;
2672 }
2673
2674 return ValidateSampleMaskiBase(context, maskNumber, mask);
2675 }
2676
ValidateMinSampleShadingOES(const Context * context,GLfloat value)2677 bool ValidateMinSampleShadingOES(const Context *context, GLfloat value)
2678 {
2679 if (!context->getExtensions().sampleShadingOES)
2680 {
2681 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2682 return false;
2683 }
2684
2685 return true;
2686 }
2687
ValidateFramebufferTextureCommon(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2688 bool ValidateFramebufferTextureCommon(const Context *context,
2689 GLenum target,
2690 GLenum attachment,
2691 TextureID texture,
2692 GLint level)
2693 {
2694 if (texture.value != 0)
2695 {
2696 Texture *tex = context->getTexture(texture);
2697
2698 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2699 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2700 // We put this validation before ValidateFramebufferTextureBase because it is an
2701 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2702 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2703 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2704 // existing texture object of type matching textarget.
2705 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2706 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2707 // three-dimensional or two-dimensional array texture.
2708 if (tex == nullptr)
2709 {
2710 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
2711 return false;
2712 }
2713
2714 if (!ValidMipLevel(context, tex->getType(), level))
2715 {
2716 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
2717 return false;
2718 }
2719 }
2720
2721 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
2722 {
2723 return false;
2724 }
2725
2726 return true;
2727 }
2728
ValidateFramebufferTextureEXT(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2729 bool ValidateFramebufferTextureEXT(const Context *context,
2730 GLenum target,
2731 GLenum attachment,
2732 TextureID texture,
2733 GLint level)
2734 {
2735 if (!context->getExtensions().geometryShaderEXT)
2736 {
2737 context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2738 return false;
2739 }
2740
2741 return ValidateFramebufferTextureCommon(context, target, attachment, texture, level);
2742 }
2743
ValidateFramebufferTextureOES(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2744 bool ValidateFramebufferTextureOES(const Context *context,
2745 GLenum target,
2746 GLenum attachment,
2747 TextureID texture,
2748 GLint level)
2749 {
2750 if (!context->getExtensions().geometryShaderOES)
2751 {
2752 context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2753 return false;
2754 }
2755
2756 return ValidateFramebufferTextureCommon(context, target, attachment, texture, level);
2757 }
2758
2759 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,TextureType target,GLsizei samples,GLenum sizedinternalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)2760 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2761 TextureType target,
2762 GLsizei samples,
2763 GLenum sizedinternalformat,
2764 GLsizei width,
2765 GLsizei height,
2766 GLsizei depth,
2767 GLboolean fixedsamplelocations)
2768 {
2769 if (!context->getExtensions().textureStorageMultisample2DArrayOES)
2770 {
2771 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
2772 return false;
2773 }
2774
2775 if (target != TextureType::_2DMultisampleArray)
2776 {
2777 context->validationError(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
2778 return false;
2779 }
2780
2781 if (width < 1 || height < 1 || depth < 1)
2782 {
2783 context->validationError(GL_INVALID_VALUE, kNegativeSize);
2784 return false;
2785 }
2786
2787 if (depth > context->getCaps().maxArrayTextureLayers)
2788 {
2789 context->validationError(GL_INVALID_VALUE, kTextureDepthOutOfRange);
2790 return false;
2791 }
2792
2793 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
2794 height);
2795 }
2796
ValidateTexStorageMem3DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)2797 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
2798 TextureType target,
2799 GLsizei samples,
2800 GLenum internalFormat,
2801 GLsizei width,
2802 GLsizei height,
2803 GLsizei depth,
2804 GLboolean fixedSampleLocations,
2805 MemoryObjectID memory,
2806 GLuint64 offset)
2807 {
2808 if (!context->getExtensions().memoryObject)
2809 {
2810 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2811 return false;
2812 }
2813
2814 UNIMPLEMENTED();
2815 return false;
2816 }
2817
ValidateGetProgramResourceLocationIndexEXT(const Context * context,ShaderProgramID program,GLenum programInterface,const char * name)2818 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
2819 ShaderProgramID program,
2820 GLenum programInterface,
2821 const char *name)
2822 {
2823 if (!context->getExtensions().blendFuncExtended)
2824 {
2825 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2826 return false;
2827 }
2828 if (context->getClientVersion() < ES_3_1)
2829 {
2830 context->validationError(GL_INVALID_OPERATION, kES31Required);
2831 return false;
2832 }
2833 if (programInterface != GL_PROGRAM_OUTPUT)
2834 {
2835 context->validationError(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
2836 return false;
2837 }
2838 Program *programObject = GetValidProgram(context, program);
2839 if (!programObject)
2840 {
2841 return false;
2842 }
2843 if (!programObject->isLinked())
2844 {
2845 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
2846 return false;
2847 }
2848 return true;
2849 }
2850
2851 // GL_OES_texture_buffer
ValidateTexBufferOES(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked)2852 bool ValidateTexBufferOES(const Context *context,
2853 TextureType target,
2854 GLenum internalformat,
2855 BufferID bufferPacked)
2856 {
2857 if (!context->getExtensions().textureBufferOES)
2858 {
2859 context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2860 return false;
2861 }
2862
2863 return ValidateTexBufferBase(context, target, internalformat, bufferPacked);
2864 }
2865
ValidateTexBufferRangeOES(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2866 bool ValidateTexBufferRangeOES(const Context *context,
2867 TextureType target,
2868 GLenum internalformat,
2869 BufferID bufferPacked,
2870 GLintptr offset,
2871 GLsizeiptr size)
2872 {
2873 if (!context->getExtensions().textureBufferOES)
2874 {
2875 context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2876 return false;
2877 }
2878
2879 return ValidateTexBufferRangeBase(context, target, internalformat, bufferPacked, offset, size);
2880 }
2881
2882 // GL_EXT_texture_buffer
ValidateTexBufferEXT(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked)2883 bool ValidateTexBufferEXT(const Context *context,
2884 TextureType target,
2885 GLenum internalformat,
2886 BufferID bufferPacked)
2887 {
2888 if (!context->getExtensions().textureBufferEXT)
2889 {
2890 context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2891 return false;
2892 }
2893
2894 return ValidateTexBufferBase(context, target, internalformat, bufferPacked);
2895 }
2896
ValidateTexBufferRangeEXT(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2897 bool ValidateTexBufferRangeEXT(const Context *context,
2898 TextureType target,
2899 GLenum internalformat,
2900 BufferID bufferPacked,
2901 GLintptr offset,
2902 GLsizeiptr size)
2903 {
2904 if (!context->getExtensions().textureBufferEXT)
2905 {
2906 context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2907 return false;
2908 }
2909
2910 return ValidateTexBufferRangeBase(context, target, internalformat, bufferPacked, offset, size);
2911 }
2912
ValidateTexBufferBase(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked)2913 bool ValidateTexBufferBase(const Context *context,
2914 TextureType target,
2915 GLenum internalformat,
2916 BufferID bufferPacked)
2917 {
2918 if (target != TextureType::Buffer)
2919 {
2920 context->validationError(GL_INVALID_ENUM, kTextureBufferTarget);
2921 return false;
2922 }
2923
2924 switch (internalformat)
2925 {
2926 case GL_R8:
2927 case GL_R16F:
2928 case GL_R32F:
2929 case GL_R8I:
2930 case GL_R16I:
2931 case GL_R32I:
2932 case GL_R8UI:
2933 case GL_R16UI:
2934 case GL_R32UI:
2935 case GL_RG8:
2936 case GL_RG16F:
2937 case GL_RG32F:
2938 case GL_RG8I:
2939 case GL_RG16I:
2940 case GL_RG32I:
2941 case GL_RG8UI:
2942 case GL_RG16UI:
2943 case GL_RG32UI:
2944 case GL_RGB32F:
2945 case GL_RGB32I:
2946 case GL_RGB32UI:
2947 case GL_RGBA8:
2948 case GL_RGBA16F:
2949 case GL_RGBA32F:
2950 case GL_RGBA8I:
2951 case GL_RGBA16I:
2952 case GL_RGBA32I:
2953 case GL_RGBA8UI:
2954 case GL_RGBA16UI:
2955 case GL_RGBA32UI:
2956 break;
2957
2958 default:
2959 context->validationError(GL_INVALID_ENUM, kTextureBufferInternalFormat);
2960 return false;
2961 }
2962
2963 if (bufferPacked.value != 0)
2964 {
2965 if (!context->isBufferGenerated(bufferPacked))
2966 {
2967 context->validationError(GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
2968 return false;
2969 }
2970 }
2971
2972 return true;
2973 }
2974
ValidateTexBufferRangeBase(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2975 bool ValidateTexBufferRangeBase(const Context *context,
2976 TextureType target,
2977 GLenum internalformat,
2978 BufferID bufferPacked,
2979 GLintptr offset,
2980 GLsizeiptr size)
2981 {
2982 const Caps &caps = context->getCaps();
2983
2984 if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
2985 {
2986 context->validationError(GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
2987 return false;
2988 }
2989 if (size <= 0)
2990 {
2991 context->validationError(GL_INVALID_VALUE, kTextureBufferSize);
2992 return false;
2993 }
2994 const Buffer *buffer = context->getBuffer(bufferPacked);
2995
2996 if (!buffer)
2997 {
2998 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
2999 return false;
3000 }
3001
3002 if (offset + size > buffer->getSize())
3003 {
3004 context->validationError(GL_INVALID_VALUE, kTextureBufferSizeOffset);
3005 return false;
3006 }
3007
3008 return ValidateTexBufferBase(context, target, internalformat, bufferPacked);
3009 }
3010
3011 } // namespace gl
3012