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().tessellationShaderEXT ||
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 switch (programInterface)
289 {
290 case GL_PROGRAM_INPUT:
291 return (index <
292 static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
293
294 case GL_PROGRAM_OUTPUT:
295 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
296
297 case GL_UNIFORM:
298 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
299
300 case GL_BUFFER_VARIABLE:
301 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
302
303 case GL_SHADER_STORAGE_BLOCK:
304 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
305
306 case GL_UNIFORM_BLOCK:
307 return (index < programObject->getActiveUniformBlockCount());
308
309 case GL_ATOMIC_COUNTER_BUFFER:
310 return (index < programObject->getActiveAtomicCounterBufferCount());
311
312 case GL_TRANSFORM_FEEDBACK_VARYING:
313 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
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.getProgramExecutable();
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
1525 return true;
1526 }
1527
ValidateGetProgramResourceLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const GLchar * name)1528 bool ValidateGetProgramResourceLocation(const Context *context,
1529 angle::EntryPoint entryPoint,
1530 ShaderProgramID program,
1531 GLenum programInterface,
1532 const GLchar *name)
1533 {
1534 if (context->getClientVersion() < ES_3_1)
1535 {
1536 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1537 return false;
1538 }
1539
1540 Program *programObject = GetValidProgram(context, entryPoint, program);
1541 if (programObject == nullptr)
1542 {
1543 return false;
1544 }
1545
1546 if (!programObject->isLinked())
1547 {
1548 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
1549 return false;
1550 }
1551
1552 if (!ValidateLocationProgramInterface(programInterface))
1553 {
1554 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
1555 return false;
1556 }
1557 return true;
1558 }
1559
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)1560 bool ValidateGetProgramResourceiv(const Context *context,
1561 angle::EntryPoint entryPoint,
1562 ShaderProgramID program,
1563 GLenum programInterface,
1564 GLuint index,
1565 GLsizei propCount,
1566 const GLenum *props,
1567 GLsizei bufSize,
1568 const GLsizei *length,
1569 const GLint *params)
1570 {
1571 if (context->getClientVersion() < ES_3_1)
1572 {
1573 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1574 return false;
1575 }
1576
1577 Program *programObject = GetValidProgram(context, entryPoint, program);
1578 if (programObject == nullptr)
1579 {
1580 return false;
1581 }
1582 if (!ValidateProgramInterface(programInterface))
1583 {
1584 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
1585 return false;
1586 }
1587 if (propCount <= 0)
1588 {
1589 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPropCount);
1590 return false;
1591 }
1592 if (bufSize < 0)
1593 {
1594 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
1595 return false;
1596 }
1597 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1598 {
1599 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1600 return false;
1601 }
1602 for (GLsizei i = 0; i < propCount; i++)
1603 {
1604 if (!ValidateProgramResourceProperty(context, entryPoint, props[i]))
1605 {
1606 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1607 return false;
1608 }
1609 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1610 {
1611 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
1612 return false;
1613 }
1614 }
1615 return true;
1616 }
1617
ValidateGetProgramInterfaceiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1618 bool ValidateGetProgramInterfaceiv(const Context *context,
1619 angle::EntryPoint entryPoint,
1620 ShaderProgramID program,
1621 GLenum programInterface,
1622 GLenum pname,
1623 const GLint *params)
1624 {
1625 if (context->getClientVersion() < ES_3_1)
1626 {
1627 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1628 return false;
1629 }
1630
1631 Program *programObject = GetValidProgram(context, entryPoint, program);
1632 if (programObject == nullptr)
1633 {
1634 return false;
1635 }
1636
1637 if (!ValidateProgramInterface(programInterface))
1638 {
1639 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
1640 return false;
1641 }
1642
1643 switch (pname)
1644 {
1645 case GL_ACTIVE_RESOURCES:
1646 case GL_MAX_NAME_LENGTH:
1647 case GL_MAX_NUM_ACTIVE_VARIABLES:
1648 break;
1649
1650 default:
1651 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
1652 return false;
1653 }
1654
1655 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1656 {
1657 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAtomicCounterResourceName);
1658 return false;
1659 }
1660
1661 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1662 {
1663 switch (programInterface)
1664 {
1665 case GL_ATOMIC_COUNTER_BUFFER:
1666 case GL_SHADER_STORAGE_BLOCK:
1667 case GL_UNIFORM_BLOCK:
1668 break;
1669
1670 default:
1671 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
1672 return false;
1673 }
1674 }
1675
1676 return true;
1677 }
1678
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1679 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1680 angle::EntryPoint entryPoint,
1681 ShaderProgramID program,
1682 GLenum programInterface,
1683 GLenum pname,
1684 GLsizei bufSize,
1685 const GLsizei *length,
1686 const GLint *params)
1687 {
1688 UNIMPLEMENTED();
1689 return false;
1690 }
1691
ValidateGenProgramPipelinesBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelines)1692 bool ValidateGenProgramPipelinesBase(const Context *context,
1693 angle::EntryPoint entryPoint,
1694 GLsizei n,
1695 const ProgramPipelineID *pipelines)
1696 {
1697 return ValidateGenOrDelete(context, entryPoint, n);
1698 }
1699
ValidateDeleteProgramPipelinesBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelines)1700 bool ValidateDeleteProgramPipelinesBase(const Context *context,
1701 angle::EntryPoint entryPoint,
1702 GLsizei n,
1703 const ProgramPipelineID *pipelines)
1704 {
1705 return ValidateGenOrDelete(context, entryPoint, n);
1706 }
1707
ValidateBindProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1708 bool ValidateBindProgramPipelineBase(const Context *context,
1709 angle::EntryPoint entryPoint,
1710 ProgramPipelineID pipeline)
1711 {
1712 if (!context->isProgramPipelineGenerated({pipeline}))
1713 {
1714 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1715 return false;
1716 }
1717
1718 return true;
1719 }
1720
ValidateIsProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1721 bool ValidateIsProgramPipelineBase(const Context *context,
1722 angle::EntryPoint entryPoint,
1723 ProgramPipelineID pipeline)
1724 {
1725 return true;
1726 }
1727
ValidateUseProgramStagesBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1728 bool ValidateUseProgramStagesBase(const Context *context,
1729 angle::EntryPoint entryPoint,
1730 ProgramPipelineID pipeline,
1731 GLbitfield stages,
1732 ShaderProgramID programId)
1733 {
1734 // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
1735 // not the reserved value GL_ALL_SHADER_BITS.
1736 GLbitfield knownShaderBits =
1737 GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1738
1739 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
1740 {
1741 knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
1742 }
1743
1744 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT)
1745 {
1746 knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
1747 knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
1748 }
1749
1750 if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1751 {
1752 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1753 return false;
1754 }
1755
1756 // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1757 // to glGenProgramPipelines or if such a name has been deleted by a call to
1758 // glDeleteProgramPipelines.
1759 if (!context->isProgramPipelineGenerated({pipeline}))
1760 {
1761 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1762 return false;
1763 }
1764
1765 // If program is zero, or refers to a program object with no valid shader executable for a given
1766 // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1767 // shader stages.
1768 if (programId.value == 0)
1769 {
1770 return true;
1771 }
1772
1773 Program *program = context->getProgramNoResolveLink(programId);
1774 if (!program)
1775 {
1776 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
1777 return false;
1778 }
1779
1780 // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1781 // with its GL_PROGRAM_SEPARABLE status set.
1782 // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1783 // glDetachShader() was not called.
1784 program->resolveLink(context);
1785 if (!program->isSeparable())
1786 {
1787 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotSeparable);
1788 return false;
1789 }
1790
1791 // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1792 // successfully linked.
1793 if (!program->isLinked())
1794 {
1795 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
1796 return false;
1797 }
1798
1799 return true;
1800 }
1801
ValidateActiveShaderProgramBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,ShaderProgramID programId)1802 bool ValidateActiveShaderProgramBase(const Context *context,
1803 angle::EntryPoint entryPoint,
1804 ProgramPipelineID pipeline,
1805 ShaderProgramID programId)
1806 {
1807 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1808 // call to GenProgramPipelines or if such a name has since been deleted by
1809 // DeleteProgramPipelines.
1810 if (!context->isProgramPipelineGenerated({pipeline}))
1811 {
1812 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1813 return false;
1814 }
1815
1816 // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1817 // program or shader object.
1818 if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1819 {
1820 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
1821 return false;
1822 }
1823
1824 // An INVALID_OPERATION error is generated if program is the name of a shader object.
1825 if (context->isShader(programId))
1826 {
1827 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
1828 return false;
1829 }
1830
1831 // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1832 // was last linked unsuccessfully. The active program is not modified.
1833 Program *program = context->getProgramNoResolveLink(programId);
1834 if ((programId.value != 0) && !program->isLinked())
1835 {
1836 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
1837 return false;
1838 }
1839
1840 return true;
1841 }
1842
ValidateCreateShaderProgramvBase(const Context * context,angle::EntryPoint entryPoint,ShaderType type,GLsizei count,const GLchar * const * strings)1843 bool ValidateCreateShaderProgramvBase(const Context *context,
1844 angle::EntryPoint entryPoint,
1845 ShaderType type,
1846 GLsizei count,
1847 const GLchar *const *strings)
1848 {
1849 switch (type)
1850 {
1851 case ShaderType::InvalidEnum:
1852 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
1853 return false;
1854 case ShaderType::Vertex:
1855 case ShaderType::Fragment:
1856 case ShaderType::Compute:
1857 break;
1858 case ShaderType::Geometry:
1859 if (!context->getExtensions().geometryShaderAny() &&
1860 context->getClientVersion() < ES_3_2)
1861 {
1862 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
1863 return false;
1864 }
1865 break;
1866 case ShaderType::TessControl:
1867 case ShaderType::TessEvaluation:
1868 if (!context->getExtensions().tessellationShaderEXT &&
1869 context->getClientVersion() < ES_3_2)
1870 {
1871 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
1872 return false;
1873 }
1874 break;
1875 default:
1876 UNREACHABLE();
1877 }
1878
1879 // GL_INVALID_VALUE is generated if count is negative.
1880 if (count < 0)
1881 {
1882 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
1883 return false;
1884 }
1885
1886 return true;
1887 }
1888
ValidateCreateShaderProgramvBase(const Context * context,angle::EntryPoint entryPoint,ShaderType type,GLsizei count,const GLchar ** strings)1889 bool ValidateCreateShaderProgramvBase(const Context *context,
1890 angle::EntryPoint entryPoint,
1891 ShaderType type,
1892 GLsizei count,
1893 const GLchar **strings)
1894 {
1895 const GLchar *const *tmpStrings = strings;
1896 return ValidateCreateShaderProgramvBase(context, entryPoint, type, count, tmpStrings);
1897 }
1898
ValidateGetProgramPipelineivBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLenum pname,const GLint * params)1899 bool ValidateGetProgramPipelineivBase(const Context *context,
1900 angle::EntryPoint entryPoint,
1901 ProgramPipelineID pipeline,
1902 GLenum pname,
1903 const GLint *params)
1904 {
1905 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1906 // call to GenProgramPipelines or if such a name has since been deleted by
1907 // DeleteProgramPipelines.
1908 if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
1909 {
1910 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1911 return false;
1912 }
1913
1914 // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
1915 // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
1916 // table 7.1.
1917 switch (pname)
1918 {
1919 case GL_ACTIVE_PROGRAM:
1920 case GL_INFO_LOG_LENGTH:
1921 case GL_VALIDATE_STATUS:
1922 case GL_VERTEX_SHADER:
1923 case GL_FRAGMENT_SHADER:
1924 case GL_COMPUTE_SHADER:
1925 break;
1926 case GL_GEOMETRY_SHADER:
1927 return context->getExtensions().geometryShaderAny() ||
1928 context->getClientVersion() >= ES_3_2;
1929 case GL_TESS_CONTROL_SHADER:
1930 case GL_TESS_EVALUATION_SHADER:
1931 return context->getExtensions().tessellationShaderEXT ||
1932 context->getClientVersion() >= ES_3_2;
1933
1934 default:
1935 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
1936 return false;
1937 }
1938
1939 return true;
1940 }
1941
ValidateValidateProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1942 bool ValidateValidateProgramPipelineBase(const Context *context,
1943 angle::EntryPoint entryPoint,
1944 ProgramPipelineID pipeline)
1945 {
1946 if (pipeline.value == 0)
1947 {
1948 return false;
1949 }
1950
1951 if (!context->isProgramPipelineGenerated(pipeline))
1952 {
1953 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1954 return false;
1955 }
1956
1957 return true;
1958 }
1959
ValidateGetProgramPipelineInfoLogBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)1960 bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
1961 angle::EntryPoint entryPoint,
1962 ProgramPipelineID pipeline,
1963 GLsizei bufSize,
1964 const GLsizei *length,
1965 const GLchar *infoLog)
1966 {
1967 if (bufSize < 0)
1968 {
1969 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
1970 return false;
1971 }
1972
1973 if (!context->isProgramPipelineGenerated(pipeline))
1974 {
1975 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
1976 return false;
1977 }
1978
1979 return true;
1980 }
1981
ValidateActiveShaderProgram(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)1982 bool ValidateActiveShaderProgram(const Context *context,
1983 angle::EntryPoint entryPoint,
1984 ProgramPipelineID pipelinePacked,
1985 ShaderProgramID programPacked)
1986 {
1987 if (context->getClientVersion() < ES_3_1)
1988 {
1989 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1990 return false;
1991 }
1992
1993 return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
1994 }
1995
ValidateBindProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)1996 bool ValidateBindProgramPipeline(const Context *context,
1997 angle::EntryPoint entryPoint,
1998 ProgramPipelineID pipelinePacked)
1999 {
2000 if (context->getClientVersion() < ES_3_1)
2001 {
2002 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2003 return false;
2004 }
2005
2006 return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
2007 }
2008
ValidateCreateShaderProgramv(const Context * context,angle::EntryPoint entryPoint,ShaderType typePacked,GLsizei count,const GLchar * const * strings)2009 bool ValidateCreateShaderProgramv(const Context *context,
2010 angle::EntryPoint entryPoint,
2011 ShaderType typePacked,
2012 GLsizei count,
2013 const GLchar *const *strings)
2014 {
2015 if (context->getClientVersion() < ES_3_1)
2016 {
2017 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2018 return false;
2019 }
2020
2021 return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
2022 }
2023
ValidateDeleteProgramPipelines(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)2024 bool ValidateDeleteProgramPipelines(const Context *context,
2025 angle::EntryPoint entryPoint,
2026 GLsizei n,
2027 const ProgramPipelineID *pipelinesPacked)
2028 {
2029 if (context->getClientVersion() < ES_3_1)
2030 {
2031 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2032 return false;
2033 }
2034
2035 return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
2036 }
2037
ValidateGenProgramPipelines(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)2038 bool ValidateGenProgramPipelines(const Context *context,
2039 angle::EntryPoint entryPoint,
2040 GLsizei n,
2041 const ProgramPipelineID *pipelinesPacked)
2042 {
2043 if (context->getClientVersion() < ES_3_1)
2044 {
2045 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2046 return false;
2047 }
2048
2049 return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
2050 }
2051
ValidateGetProgramPipelineInfoLog(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)2052 bool ValidateGetProgramPipelineInfoLog(const Context *context,
2053 angle::EntryPoint entryPoint,
2054 ProgramPipelineID pipelinePacked,
2055 GLsizei bufSize,
2056 const GLsizei *length,
2057 const GLchar *infoLog)
2058 {
2059 if (context->getClientVersion() < ES_3_1)
2060 {
2061 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2062 return false;
2063 }
2064
2065 return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
2066 length, infoLog);
2067 }
2068
ValidateGetProgramPipelineiv(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)2069 bool ValidateGetProgramPipelineiv(const Context *context,
2070 angle::EntryPoint entryPoint,
2071 ProgramPipelineID pipelinePacked,
2072 GLenum pname,
2073 const GLint *params)
2074 {
2075 if (context->getClientVersion() < ES_3_1)
2076 {
2077 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2078 return false;
2079 }
2080
2081 return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
2082 }
2083
ValidateIsProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2084 bool ValidateIsProgramPipeline(const Context *context,
2085 angle::EntryPoint entryPoint,
2086 ProgramPipelineID pipelinePacked)
2087 {
2088 if (context->getClientVersion() < ES_3_1)
2089 {
2090 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2091 return false;
2092 }
2093
2094 return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
2095 }
2096
ValidateProgramUniform1f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)2097 bool ValidateProgramUniform1f(const Context *context,
2098 angle::EntryPoint entryPoint,
2099 ShaderProgramID programPacked,
2100 UniformLocation locationPacked,
2101 GLfloat v0)
2102 {
2103 if (context->getClientVersion() < ES_3_1)
2104 {
2105 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2106 return false;
2107 }
2108
2109 return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
2110 }
2111
ValidateProgramUniform1fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2112 bool ValidateProgramUniform1fv(const Context *context,
2113 angle::EntryPoint entryPoint,
2114 ShaderProgramID programPacked,
2115 UniformLocation locationPacked,
2116 GLsizei count,
2117 const GLfloat *value)
2118 {
2119 if (context->getClientVersion() < ES_3_1)
2120 {
2121 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2122 return false;
2123 }
2124
2125 return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
2126 value);
2127 }
2128
ValidateProgramUniform1i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)2129 bool ValidateProgramUniform1i(const Context *context,
2130 angle::EntryPoint entryPoint,
2131 ShaderProgramID programPacked,
2132 UniformLocation locationPacked,
2133 GLint v0)
2134 {
2135 if (context->getClientVersion() < ES_3_1)
2136 {
2137 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2138 return false;
2139 }
2140
2141 return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
2142 }
2143
ValidateProgramUniform1iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2144 bool ValidateProgramUniform1iv(const Context *context,
2145 angle::EntryPoint entryPoint,
2146 ShaderProgramID programPacked,
2147 UniformLocation locationPacked,
2148 GLsizei count,
2149 const GLint *value)
2150 {
2151 if (context->getClientVersion() < ES_3_1)
2152 {
2153 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2154 return false;
2155 }
2156
2157 return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
2158 value);
2159 }
2160
ValidateProgramUniform1ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)2161 bool ValidateProgramUniform1ui(const Context *context,
2162 angle::EntryPoint entryPoint,
2163 ShaderProgramID programPacked,
2164 UniformLocation locationPacked,
2165 GLuint v0)
2166 {
2167 if (context->getClientVersion() < ES_3_1)
2168 {
2169 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2170 return false;
2171 }
2172
2173 return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
2174 }
2175
ValidateProgramUniform1uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2176 bool ValidateProgramUniform1uiv(const Context *context,
2177 angle::EntryPoint entryPoint,
2178 ShaderProgramID programPacked,
2179 UniformLocation locationPacked,
2180 GLsizei count,
2181 const GLuint *value)
2182 {
2183 if (context->getClientVersion() < ES_3_1)
2184 {
2185 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2186 return false;
2187 }
2188
2189 return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
2190 value);
2191 }
2192
ValidateProgramUniform2f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)2193 bool ValidateProgramUniform2f(const Context *context,
2194 angle::EntryPoint entryPoint,
2195 ShaderProgramID programPacked,
2196 UniformLocation locationPacked,
2197 GLfloat v0,
2198 GLfloat v1)
2199 {
2200 if (context->getClientVersion() < ES_3_1)
2201 {
2202 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2203 return false;
2204 }
2205
2206 return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
2207 }
2208
ValidateProgramUniform2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2209 bool ValidateProgramUniform2fv(const Context *context,
2210 angle::EntryPoint entryPoint,
2211 ShaderProgramID programPacked,
2212 UniformLocation locationPacked,
2213 GLsizei count,
2214 const GLfloat *value)
2215 {
2216 if (context->getClientVersion() < ES_3_1)
2217 {
2218 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2219 return false;
2220 }
2221
2222 return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
2223 value);
2224 }
2225
ValidateProgramUniform2i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)2226 bool ValidateProgramUniform2i(const Context *context,
2227 angle::EntryPoint entryPoint,
2228 ShaderProgramID programPacked,
2229 UniformLocation locationPacked,
2230 GLint v0,
2231 GLint v1)
2232 {
2233 if (context->getClientVersion() < ES_3_1)
2234 {
2235 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2236 return false;
2237 }
2238
2239 return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
2240 }
2241
ValidateProgramUniform2iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2242 bool ValidateProgramUniform2iv(const Context *context,
2243 angle::EntryPoint entryPoint,
2244 ShaderProgramID programPacked,
2245 UniformLocation locationPacked,
2246 GLsizei count,
2247 const GLint *value)
2248 {
2249 if (context->getClientVersion() < ES_3_1)
2250 {
2251 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2252 return false;
2253 }
2254
2255 return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
2256 value);
2257 }
2258
ValidateProgramUniform2ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)2259 bool ValidateProgramUniform2ui(const Context *context,
2260 angle::EntryPoint entryPoint,
2261 ShaderProgramID programPacked,
2262 UniformLocation locationPacked,
2263 GLuint v0,
2264 GLuint v1)
2265 {
2266 if (context->getClientVersion() < ES_3_1)
2267 {
2268 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2269 return false;
2270 }
2271
2272 return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
2273 v1);
2274 }
2275
ValidateProgramUniform2uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2276 bool ValidateProgramUniform2uiv(const Context *context,
2277 angle::EntryPoint entryPoint,
2278 ShaderProgramID programPacked,
2279 UniformLocation locationPacked,
2280 GLsizei count,
2281 const GLuint *value)
2282 {
2283 if (context->getClientVersion() < ES_3_1)
2284 {
2285 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2286 return false;
2287 }
2288
2289 return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
2290 value);
2291 }
2292
ValidateProgramUniform3f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)2293 bool ValidateProgramUniform3f(const Context *context,
2294 angle::EntryPoint entryPoint,
2295 ShaderProgramID programPacked,
2296 UniformLocation locationPacked,
2297 GLfloat v0,
2298 GLfloat v1,
2299 GLfloat v2)
2300 {
2301 if (context->getClientVersion() < ES_3_1)
2302 {
2303 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2304 return false;
2305 }
2306
2307 return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2308 v2);
2309 }
2310
ValidateProgramUniform3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2311 bool ValidateProgramUniform3fv(const Context *context,
2312 angle::EntryPoint entryPoint,
2313 ShaderProgramID programPacked,
2314 UniformLocation locationPacked,
2315 GLsizei count,
2316 const GLfloat *value)
2317 {
2318 if (context->getClientVersion() < ES_3_1)
2319 {
2320 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2321 return false;
2322 }
2323
2324 return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
2325 value);
2326 }
2327
ValidateProgramUniform3i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)2328 bool ValidateProgramUniform3i(const Context *context,
2329 angle::EntryPoint entryPoint,
2330 ShaderProgramID programPacked,
2331 UniformLocation locationPacked,
2332 GLint v0,
2333 GLint v1,
2334 GLint v2)
2335 {
2336 if (context->getClientVersion() < ES_3_1)
2337 {
2338 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2339 return false;
2340 }
2341
2342 return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2343 v2);
2344 }
2345
ValidateProgramUniform3iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2346 bool ValidateProgramUniform3iv(const Context *context,
2347 angle::EntryPoint entryPoint,
2348 ShaderProgramID programPacked,
2349 UniformLocation locationPacked,
2350 GLsizei count,
2351 const GLint *value)
2352 {
2353 if (context->getClientVersion() < ES_3_1)
2354 {
2355 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2356 return false;
2357 }
2358
2359 return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
2360 value);
2361 }
2362
ValidateProgramUniform3ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)2363 bool ValidateProgramUniform3ui(const Context *context,
2364 angle::EntryPoint entryPoint,
2365 ShaderProgramID programPacked,
2366 UniformLocation locationPacked,
2367 GLuint v0,
2368 GLuint v1,
2369 GLuint v2)
2370 {
2371 if (context->getClientVersion() < ES_3_1)
2372 {
2373 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2374 return false;
2375 }
2376
2377 return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2378 v2);
2379 }
2380
ValidateProgramUniform3uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2381 bool ValidateProgramUniform3uiv(const Context *context,
2382 angle::EntryPoint entryPoint,
2383 ShaderProgramID programPacked,
2384 UniformLocation locationPacked,
2385 GLsizei count,
2386 const GLuint *value)
2387 {
2388 if (context->getClientVersion() < ES_3_1)
2389 {
2390 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2391 return false;
2392 }
2393
2394 return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
2395 value);
2396 }
2397
ValidateProgramUniform4f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)2398 bool ValidateProgramUniform4f(const Context *context,
2399 angle::EntryPoint entryPoint,
2400 ShaderProgramID programPacked,
2401 UniformLocation locationPacked,
2402 GLfloat v0,
2403 GLfloat v1,
2404 GLfloat v2,
2405 GLfloat v3)
2406 {
2407 if (context->getClientVersion() < ES_3_1)
2408 {
2409 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2410 return false;
2411 }
2412
2413 return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2414 v2, v3);
2415 }
2416
ValidateProgramUniform4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2417 bool ValidateProgramUniform4fv(const Context *context,
2418 angle::EntryPoint entryPoint,
2419 ShaderProgramID programPacked,
2420 UniformLocation locationPacked,
2421 GLsizei count,
2422 const GLfloat *value)
2423 {
2424 if (context->getClientVersion() < ES_3_1)
2425 {
2426 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2427 return false;
2428 }
2429
2430 return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
2431 value);
2432 }
2433
ValidateProgramUniform4i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)2434 bool ValidateProgramUniform4i(const Context *context,
2435 angle::EntryPoint entryPoint,
2436 ShaderProgramID programPacked,
2437 UniformLocation locationPacked,
2438 GLint v0,
2439 GLint v1,
2440 GLint v2,
2441 GLint v3)
2442 {
2443 if (context->getClientVersion() < ES_3_1)
2444 {
2445 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2446 return false;
2447 }
2448
2449 return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2450 v2, v3);
2451 }
2452
ValidateProgramUniform4iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2453 bool ValidateProgramUniform4iv(const Context *context,
2454 angle::EntryPoint entryPoint,
2455 ShaderProgramID programPacked,
2456 UniformLocation locationPacked,
2457 GLsizei count,
2458 const GLint *value)
2459 {
2460 if (context->getClientVersion() < ES_3_1)
2461 {
2462 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2463 return false;
2464 }
2465
2466 return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
2467 value);
2468 }
2469
ValidateProgramUniform4ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)2470 bool ValidateProgramUniform4ui(const Context *context,
2471 angle::EntryPoint entryPoint,
2472 ShaderProgramID programPacked,
2473 UniformLocation locationPacked,
2474 GLuint v0,
2475 GLuint v1,
2476 GLuint v2,
2477 GLuint v3)
2478 {
2479 if (context->getClientVersion() < ES_3_1)
2480 {
2481 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2482 return false;
2483 }
2484
2485 return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2486 v2, v3);
2487 }
2488
ValidateProgramUniform4uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2489 bool ValidateProgramUniform4uiv(const Context *context,
2490 angle::EntryPoint entryPoint,
2491 ShaderProgramID programPacked,
2492 UniformLocation locationPacked,
2493 GLsizei count,
2494 const GLuint *value)
2495 {
2496 if (context->getClientVersion() < ES_3_1)
2497 {
2498 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2499 return false;
2500 }
2501
2502 return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
2503 value);
2504 }
2505
ValidateProgramUniformMatrix2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2506 bool ValidateProgramUniformMatrix2fv(const Context *context,
2507 angle::EntryPoint entryPoint,
2508 ShaderProgramID programPacked,
2509 UniformLocation locationPacked,
2510 GLsizei count,
2511 GLboolean transpose,
2512 const GLfloat *value)
2513 {
2514 if (context->getClientVersion() < ES_3_1)
2515 {
2516 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2517 return false;
2518 }
2519
2520 return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
2521 count, transpose, value);
2522 }
2523
ValidateProgramUniformMatrix2x3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2524 bool ValidateProgramUniformMatrix2x3fv(const Context *context,
2525 angle::EntryPoint entryPoint,
2526 ShaderProgramID programPacked,
2527 UniformLocation locationPacked,
2528 GLsizei count,
2529 GLboolean transpose,
2530 const GLfloat *value)
2531 {
2532 if (context->getClientVersion() < ES_3_1)
2533 {
2534 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2535 return false;
2536 }
2537
2538 return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
2539 count, transpose, value);
2540 }
2541
ValidateProgramUniformMatrix2x4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2542 bool ValidateProgramUniformMatrix2x4fv(const Context *context,
2543 angle::EntryPoint entryPoint,
2544 ShaderProgramID programPacked,
2545 UniformLocation locationPacked,
2546 GLsizei count,
2547 GLboolean transpose,
2548 const GLfloat *value)
2549 {
2550 if (context->getClientVersion() < ES_3_1)
2551 {
2552 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2553 return false;
2554 }
2555
2556 return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
2557 count, transpose, value);
2558 }
2559
ValidateProgramUniformMatrix3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2560 bool ValidateProgramUniformMatrix3fv(const Context *context,
2561 angle::EntryPoint entryPoint,
2562 ShaderProgramID programPacked,
2563 UniformLocation locationPacked,
2564 GLsizei count,
2565 GLboolean transpose,
2566 const GLfloat *value)
2567 {
2568 if (context->getClientVersion() < ES_3_1)
2569 {
2570 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2571 return false;
2572 }
2573
2574 return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
2575 count, transpose, value);
2576 }
2577
ValidateProgramUniformMatrix3x2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2578 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
2579 angle::EntryPoint entryPoint,
2580 ShaderProgramID programPacked,
2581 UniformLocation locationPacked,
2582 GLsizei count,
2583 GLboolean transpose,
2584 const GLfloat *value)
2585 {
2586 if (context->getClientVersion() < ES_3_1)
2587 {
2588 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2589 return false;
2590 }
2591
2592 return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
2593 count, transpose, value);
2594 }
2595
ValidateProgramUniformMatrix3x4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2596 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
2597 angle::EntryPoint entryPoint,
2598 ShaderProgramID programPacked,
2599 UniformLocation locationPacked,
2600 GLsizei count,
2601 GLboolean transpose,
2602 const GLfloat *value)
2603 {
2604 if (context->getClientVersion() < ES_3_1)
2605 {
2606 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2607 return false;
2608 }
2609
2610 return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
2611 count, transpose, value);
2612 }
2613
ValidateProgramUniformMatrix4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2614 bool ValidateProgramUniformMatrix4fv(const Context *context,
2615 angle::EntryPoint entryPoint,
2616 ShaderProgramID programPacked,
2617 UniformLocation locationPacked,
2618 GLsizei count,
2619 GLboolean transpose,
2620 const GLfloat *value)
2621 {
2622 if (context->getClientVersion() < ES_3_1)
2623 {
2624 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2625 return false;
2626 }
2627
2628 return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
2629 count, transpose, value);
2630 }
2631
ValidateProgramUniformMatrix4x2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2632 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
2633 angle::EntryPoint entryPoint,
2634 ShaderProgramID programPacked,
2635 UniformLocation locationPacked,
2636 GLsizei count,
2637 GLboolean transpose,
2638 const GLfloat *value)
2639 {
2640 if (context->getClientVersion() < ES_3_1)
2641 {
2642 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2643 return false;
2644 }
2645
2646 return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
2647 count, transpose, value);
2648 }
2649
ValidateProgramUniformMatrix4x3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2650 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
2651 angle::EntryPoint entryPoint,
2652 ShaderProgramID programPacked,
2653 UniformLocation locationPacked,
2654 GLsizei count,
2655 GLboolean transpose,
2656 const GLfloat *value)
2657 {
2658 if (context->getClientVersion() < ES_3_1)
2659 {
2660 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2661 return false;
2662 }
2663
2664 return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
2665 count, transpose, value);
2666 }
2667
ValidateUseProgramStages(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)2668 bool ValidateUseProgramStages(const Context *context,
2669 angle::EntryPoint entryPoint,
2670 ProgramPipelineID pipelinePacked,
2671 GLbitfield stages,
2672 ShaderProgramID programPacked)
2673 {
2674 if (context->getClientVersion() < ES_3_1)
2675 {
2676 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2677 return false;
2678 }
2679
2680 return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
2681 }
2682
ValidateValidateProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2683 bool ValidateValidateProgramPipeline(const Context *context,
2684 angle::EntryPoint entryPoint,
2685 ProgramPipelineID pipelinePacked)
2686 {
2687 if (context->getClientVersion() < ES_3_1)
2688 {
2689 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2690 return false;
2691 }
2692
2693 return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
2694 }
2695
ValidateMemoryBarrier(const Context * context,angle::EntryPoint entryPoint,GLbitfield barriers)2696 bool ValidateMemoryBarrier(const Context *context,
2697 angle::EntryPoint entryPoint,
2698 GLbitfield barriers)
2699 {
2700 if (context->getClientVersion() < ES_3_1)
2701 {
2702 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2703 return false;
2704 }
2705
2706 if (barriers == GL_ALL_BARRIER_BITS)
2707 {
2708 return true;
2709 }
2710
2711 GLbitfield supported_barrier_bits =
2712 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
2713 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
2714 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
2715 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
2716 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
2717
2718 if (context->getExtensions().bufferStorageEXT)
2719 {
2720 supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
2721 }
2722
2723 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2724 {
2725 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2726 return false;
2727 }
2728
2729 return true;
2730 }
2731
ValidateMemoryBarrierByRegion(const Context * context,angle::EntryPoint entryPoint,GLbitfield barriers)2732 bool ValidateMemoryBarrierByRegion(const Context *context,
2733 angle::EntryPoint entryPoint,
2734 GLbitfield barriers)
2735 {
2736 if (context->getClientVersion() < ES_3_1)
2737 {
2738 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2739 return false;
2740 }
2741
2742 if (barriers == GL_ALL_BARRIER_BITS)
2743 {
2744 return true;
2745 }
2746
2747 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
2748 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
2749 GL_SHADER_STORAGE_BARRIER_BIT |
2750 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
2751 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2752 {
2753 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2754 return false;
2755 }
2756
2757 return true;
2758 }
2759
ValidateSampleMaski(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint maskNumber,GLbitfield mask)2760 bool ValidateSampleMaski(const PrivateState &state,
2761 ErrorSet *errors,
2762 angle::EntryPoint entryPoint,
2763 GLuint maskNumber,
2764 GLbitfield mask)
2765 {
2766 if (state.getClientVersion() < ES_3_1)
2767 {
2768 errors->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2769 return false;
2770 }
2771
2772 return ValidateSampleMaskiBase(state, errors, entryPoint, maskNumber, mask);
2773 }
2774
ValidateMinSampleShadingOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat value)2775 bool ValidateMinSampleShadingOES(const PrivateState &state,
2776 ErrorSet *errors,
2777 angle::EntryPoint entryPoint,
2778 GLfloat value)
2779 {
2780 if (!state.getExtensions().sampleShadingOES)
2781 {
2782 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
2783 return false;
2784 }
2785
2786 return true;
2787 }
2788
ValidateFramebufferTextureCommon(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2789 bool ValidateFramebufferTextureCommon(const Context *context,
2790 angle::EntryPoint entryPoint,
2791 GLenum target,
2792 GLenum attachment,
2793 TextureID texture,
2794 GLint level)
2795 {
2796 if (texture.value != 0)
2797 {
2798 Texture *tex = context->getTexture(texture);
2799
2800 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2801 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2802 // We put this validation before ValidateFramebufferTextureBase because it is an
2803 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2804 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2805 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2806 // existing texture object of type matching textarget.
2807 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2808 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2809 // three-dimensional or two-dimensional array texture.
2810 if (tex == nullptr)
2811 {
2812 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
2813 return false;
2814 }
2815
2816 if (!ValidMipLevel(context, tex->getType(), level))
2817 {
2818 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
2819 return false;
2820 }
2821
2822 // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2823 // If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero.
2824 if (tex->getType() == TextureType::_2DMultisample && level != 0)
2825 {
2826 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kLevelNotZero);
2827 return false;
2828 }
2829
2830 // [OES_texture_storage_multisample_2d_array] Section 9.2.2 "Attaching Images to Framebuffer
2831 // Objects"
2832 // If texture is a two-dimensional multisample array texture, then level must be zero.
2833 if (context->getExtensions().textureStorageMultisample2dArrayOES &&
2834 tex->getType() == TextureType::_2DMultisampleArray && level != 0)
2835 {
2836 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kLevelNotZero);
2837 return false;
2838 }
2839 }
2840
2841 if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
2842 {
2843 return false;
2844 }
2845
2846 return true;
2847 }
2848
ValidateFramebufferTextureEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2849 bool ValidateFramebufferTextureEXT(const Context *context,
2850 angle::EntryPoint entryPoint,
2851 GLenum target,
2852 GLenum attachment,
2853 TextureID texture,
2854 GLint level)
2855 {
2856 if (!context->getExtensions().geometryShaderEXT)
2857 {
2858 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2859 return false;
2860 }
2861
2862 return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
2863 level);
2864 }
2865
ValidateFramebufferTextureOES(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2866 bool ValidateFramebufferTextureOES(const Context *context,
2867 angle::EntryPoint entryPoint,
2868 GLenum target,
2869 GLenum attachment,
2870 TextureID texture,
2871 GLint level)
2872 {
2873 if (!context->getExtensions().geometryShaderOES)
2874 {
2875 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2876 return false;
2877 }
2878
2879 return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
2880 level);
2881 }
2882
2883 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum sizedinternalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)2884 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2885 angle::EntryPoint entryPoint,
2886 TextureType target,
2887 GLsizei samples,
2888 GLenum sizedinternalformat,
2889 GLsizei width,
2890 GLsizei height,
2891 GLsizei depth,
2892 GLboolean fixedsamplelocations)
2893 {
2894 if (!context->getExtensions().textureStorageMultisample2dArrayOES)
2895 {
2896 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
2897 return false;
2898 }
2899
2900 if (target != TextureType::_2DMultisampleArray)
2901 {
2902 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
2903 return false;
2904 }
2905
2906 if (width < 1 || height < 1 || depth < 1)
2907 {
2908 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
2909 return false;
2910 }
2911
2912 if (depth > context->getCaps().maxArrayTextureLayers)
2913 {
2914 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureDepthOutOfRange);
2915 return false;
2916 }
2917
2918 return ValidateTexStorageMultisample(context, entryPoint, target, samples, sizedinternalformat,
2919 width, height);
2920 }
2921
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)2922 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
2923 angle::EntryPoint entryPoint,
2924 TextureType target,
2925 GLsizei samples,
2926 GLenum internalFormat,
2927 GLsizei width,
2928 GLsizei height,
2929 GLsizei depth,
2930 GLboolean fixedSampleLocations,
2931 MemoryObjectID memory,
2932 GLuint64 offset)
2933 {
2934 if (!context->getExtensions().memoryObjectEXT)
2935 {
2936 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2937 return false;
2938 }
2939
2940 UNIMPLEMENTED();
2941 return false;
2942 }
2943
ValidateGetProgramResourceLocationIndexEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const char * name)2944 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
2945 angle::EntryPoint entryPoint,
2946 ShaderProgramID program,
2947 GLenum programInterface,
2948 const char *name)
2949 {
2950 if (!context->getExtensions().blendFuncExtendedEXT)
2951 {
2952 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2953 return false;
2954 }
2955 if (context->getClientVersion() < ES_3_1)
2956 {
2957 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2958 return false;
2959 }
2960 if (programInterface != GL_PROGRAM_OUTPUT)
2961 {
2962 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
2963 return false;
2964 }
2965 Program *programObject = GetValidProgram(context, entryPoint, program);
2966 if (!programObject)
2967 {
2968 return false;
2969 }
2970 if (!programObject->isLinked())
2971 {
2972 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
2973 return false;
2974 }
2975 return true;
2976 }
2977
2978 // GL_OES_texture_buffer
ValidateTexBufferOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)2979 bool ValidateTexBufferOES(const Context *context,
2980 angle::EntryPoint entryPoint,
2981 TextureType target,
2982 GLenum internalformat,
2983 BufferID bufferPacked)
2984 {
2985 if (!context->getExtensions().textureBufferOES)
2986 {
2987 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2988 return false;
2989 }
2990
2991 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
2992 }
2993
ValidateTexBufferRangeOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2994 bool ValidateTexBufferRangeOES(const Context *context,
2995 angle::EntryPoint entryPoint,
2996 TextureType target,
2997 GLenum internalformat,
2998 BufferID bufferPacked,
2999 GLintptr offset,
3000 GLsizeiptr size)
3001 {
3002 if (!context->getExtensions().textureBufferOES)
3003 {
3004 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
3005 return false;
3006 }
3007
3008 return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
3009 offset, size);
3010 }
3011
3012 // GL_EXT_texture_buffer
ValidateTexBufferEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3013 bool ValidateTexBufferEXT(const Context *context,
3014 angle::EntryPoint entryPoint,
3015 TextureType target,
3016 GLenum internalformat,
3017 BufferID bufferPacked)
3018 {
3019 if (!context->getExtensions().textureBufferEXT)
3020 {
3021 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
3022 return false;
3023 }
3024
3025 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3026 }
3027
ValidateTexBufferRangeEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3028 bool ValidateTexBufferRangeEXT(const Context *context,
3029 angle::EntryPoint entryPoint,
3030 TextureType target,
3031 GLenum internalformat,
3032 BufferID bufferPacked,
3033 GLintptr offset,
3034 GLsizeiptr size)
3035 {
3036 if (!context->getExtensions().textureBufferEXT)
3037 {
3038 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
3039 return false;
3040 }
3041
3042 return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
3043 offset, size);
3044 }
3045
ValidateTexBufferBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3046 bool ValidateTexBufferBase(const Context *context,
3047 angle::EntryPoint entryPoint,
3048 TextureType target,
3049 GLenum internalformat,
3050 BufferID bufferPacked)
3051 {
3052 if (target != TextureType::Buffer)
3053 {
3054 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferTarget);
3055 return false;
3056 }
3057
3058 switch (internalformat)
3059 {
3060 case GL_R8:
3061 case GL_R16F:
3062 case GL_R32F:
3063 case GL_R8I:
3064 case GL_R16I:
3065 case GL_R32I:
3066 case GL_R8UI:
3067 case GL_R16UI:
3068 case GL_R32UI:
3069 case GL_RG8:
3070 case GL_RG16F:
3071 case GL_RG32F:
3072 case GL_RG8I:
3073 case GL_RG16I:
3074 case GL_RG32I:
3075 case GL_RG8UI:
3076 case GL_RG16UI:
3077 case GL_RG32UI:
3078 case GL_RGB32F:
3079 case GL_RGB32I:
3080 case GL_RGB32UI:
3081 case GL_RGBA8:
3082 case GL_RGBA16F:
3083 case GL_RGBA32F:
3084 case GL_RGBA8I:
3085 case GL_RGBA16I:
3086 case GL_RGBA32I:
3087 case GL_RGBA8UI:
3088 case GL_RGBA16UI:
3089 case GL_RGBA32UI:
3090 break;
3091
3092 default:
3093 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferInternalFormat);
3094 return false;
3095 }
3096
3097 if (bufferPacked.value != 0)
3098 {
3099 if (!context->isBufferGenerated(bufferPacked))
3100 {
3101 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
3102 return false;
3103 }
3104 }
3105
3106 return true;
3107 }
3108
ValidateTexBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3109 bool ValidateTexBufferRangeBase(const Context *context,
3110 angle::EntryPoint entryPoint,
3111 TextureType target,
3112 GLenum internalformat,
3113 BufferID bufferPacked,
3114 GLintptr offset,
3115 GLsizeiptr size)
3116 {
3117 const Caps &caps = context->getCaps();
3118
3119 if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
3120 {
3121 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
3122 return false;
3123 }
3124 if (size <= 0)
3125 {
3126 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferSize);
3127 return false;
3128 }
3129 const Buffer *buffer = context->getBuffer(bufferPacked);
3130
3131 if (!buffer)
3132 {
3133 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3134 return false;
3135 }
3136
3137 if (offset + size > buffer->getSize())
3138 {
3139 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferSizeOffset);
3140 return false;
3141 }
3142
3143 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3144 }
3145
3146 } // namespace gl
3147