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