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