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