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 if (!ValidFramebufferTarget(context, target))
1114 {
1115 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
1116 return false;
1117 }
1118
1119 switch (pname)
1120 {
1121 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1122 {
1123 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1124 if (param < 0 || param > maxWidth)
1125 {
1126 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferWidth);
1127 return false;
1128 }
1129 break;
1130 }
1131 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1132 {
1133 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1134 if (param < 0 || param > maxHeight)
1135 {
1136 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferHeight);
1137 return false;
1138 }
1139 break;
1140 }
1141 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1142 {
1143 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1144 if (param < 0 || param > maxSamples)
1145 {
1146 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferSamples);
1147 return false;
1148 }
1149 break;
1150 }
1151 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1152 {
1153 break;
1154 }
1155 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1156 {
1157 if (!context->getExtensions().geometryShaderAny() &&
1158 context->getClientVersion() < ES_3_2)
1159 {
1160 context->validationError(entryPoint, GL_INVALID_ENUM,
1161 kGeometryShaderExtensionNotEnabled);
1162 return false;
1163 }
1164 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1165 if (param < 0 || param > maxLayers)
1166 {
1167 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferLayer);
1168 return false;
1169 }
1170 break;
1171 }
1172 default:
1173 {
1174 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
1175 return false;
1176 }
1177 }
1178
1179 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1180 ASSERT(framebuffer);
1181 if (framebuffer->isDefault())
1182 {
1183 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebuffer);
1184 return false;
1185 }
1186 return true;
1187 }
1188
ValidateGetFramebufferParameteriv(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)1189 bool ValidateGetFramebufferParameteriv(const Context *context,
1190 angle::EntryPoint entryPoint,
1191 GLenum target,
1192 GLenum pname,
1193 const GLint *params)
1194 {
1195 if (context->getClientVersion() < ES_3_1)
1196 {
1197 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1198 return false;
1199 }
1200
1201 if (!ValidFramebufferTarget(context, target))
1202 {
1203 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
1204 return false;
1205 }
1206
1207 switch (pname)
1208 {
1209 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1210 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1211 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1212 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1213 break;
1214 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1215 if (!context->getExtensions().geometryShaderAny() &&
1216 context->getClientVersion() < ES_3_2)
1217 {
1218 context->validationError(entryPoint, GL_INVALID_ENUM,
1219 kGeometryShaderExtensionNotEnabled);
1220 return false;
1221 }
1222 break;
1223 default:
1224 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
1225 return false;
1226 }
1227
1228 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1229 ASSERT(framebuffer);
1230
1231 if (framebuffer->isDefault())
1232 {
1233 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebuffer);
1234 return false;
1235 }
1236 return true;
1237 }
1238
ValidateGetFramebufferParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1239 bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
1240 angle::EntryPoint entryPoint,
1241 GLenum target,
1242 GLenum pname,
1243 GLsizei bufSize,
1244 const GLsizei *length,
1245 const GLint *params)
1246 {
1247 UNIMPLEMENTED();
1248 return false;
1249 }
1250
ValidateGetProgramResourceIndex(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const GLchar * name)1251 bool ValidateGetProgramResourceIndex(const Context *context,
1252 angle::EntryPoint entryPoint,
1253 ShaderProgramID program,
1254 GLenum programInterface,
1255 const GLchar *name)
1256 {
1257 if (context->getClientVersion() < ES_3_1)
1258 {
1259 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1260 return false;
1261 }
1262
1263 Program *programObject = GetValidProgram(context, entryPoint, program);
1264 if (programObject == nullptr)
1265 {
1266 return false;
1267 }
1268
1269 if (!ValidateNamedProgramInterface(programInterface))
1270 {
1271 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
1272 return false;
1273 }
1274
1275 return true;
1276 }
1277
ValidateBindVertexBuffer(const Context * context,angle::EntryPoint entryPoint,GLuint bindingIndex,BufferID buffer,GLintptr offset,GLsizei stride)1278 bool ValidateBindVertexBuffer(const Context *context,
1279 angle::EntryPoint entryPoint,
1280 GLuint bindingIndex,
1281 BufferID buffer,
1282 GLintptr offset,
1283 GLsizei stride)
1284 {
1285 if (context->getClientVersion() < ES_3_1)
1286 {
1287 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1288 return false;
1289 }
1290
1291 if (!context->isBufferGenerated(buffer))
1292 {
1293 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
1294 return false;
1295 }
1296
1297 const Caps &caps = context->getCaps();
1298 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1299 {
1300 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1301 return false;
1302 }
1303
1304 if (offset < 0)
1305 {
1306 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
1307 return false;
1308 }
1309
1310 if (stride < 0 || stride > caps.maxVertexAttribStride)
1311 {
1312 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
1313 return false;
1314 }
1315
1316 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1317 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1318 if (context->getState().getVertexArrayId().value == 0)
1319 {
1320 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
1321 return false;
1322 }
1323
1324 return true;
1325 }
1326
ValidateVertexBindingDivisor(const Context * context,angle::EntryPoint entryPoint,GLuint bindingIndex,GLuint divisor)1327 bool ValidateVertexBindingDivisor(const Context *context,
1328 angle::EntryPoint entryPoint,
1329 GLuint bindingIndex,
1330 GLuint divisor)
1331 {
1332 if (context->getClientVersion() < ES_3_1)
1333 {
1334 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1335 return false;
1336 }
1337
1338 const Caps &caps = context->getCaps();
1339 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1340 {
1341 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1342 return false;
1343 }
1344
1345 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1346 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1347 if (context->getState().getVertexArrayId().value == 0)
1348 {
1349 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
1350 return false;
1351 }
1352
1353 return true;
1354 }
1355
ValidateVertexAttribFormat(const Context * context,angle::EntryPoint entryPoint,GLuint attribindex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeoffset)1356 bool ValidateVertexAttribFormat(const Context *context,
1357 angle::EntryPoint entryPoint,
1358 GLuint attribindex,
1359 GLint size,
1360 VertexAttribType type,
1361 GLboolean normalized,
1362 GLuint relativeoffset)
1363 {
1364 if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset))
1365 {
1366 return false;
1367 }
1368
1369 return ValidateFloatVertexFormat(context, entryPoint, attribindex, size, type);
1370 }
1371
ValidateVertexAttribIFormat(const Context * context,angle::EntryPoint entryPoint,GLuint attribindex,GLint size,VertexAttribType type,GLuint relativeoffset)1372 bool ValidateVertexAttribIFormat(const Context *context,
1373 angle::EntryPoint entryPoint,
1374 GLuint attribindex,
1375 GLint size,
1376 VertexAttribType type,
1377 GLuint relativeoffset)
1378 {
1379 if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset))
1380 {
1381 return false;
1382 }
1383
1384 return ValidateIntegerVertexFormat(context, entryPoint, attribindex, size, type);
1385 }
1386
ValidateVertexAttribBinding(const Context * context,angle::EntryPoint entryPoint,GLuint attribIndex,GLuint bindingIndex)1387 bool ValidateVertexAttribBinding(const Context *context,
1388 angle::EntryPoint entryPoint,
1389 GLuint attribIndex,
1390 GLuint bindingIndex)
1391 {
1392 if (context->getClientVersion() < ES_3_1)
1393 {
1394 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1395 return false;
1396 }
1397
1398 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1399 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1400 if (context->getState().getVertexArrayId().value == 0)
1401 {
1402 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
1403 return false;
1404 }
1405
1406 const Caps &caps = context->getCaps();
1407 if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
1408 {
1409 context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
1410 return false;
1411 }
1412
1413 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1414 {
1415 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1416 return false;
1417 }
1418
1419 return true;
1420 }
1421
ValidateGetProgramResourceName(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,const GLsizei * length,const GLchar * name)1422 bool ValidateGetProgramResourceName(const Context *context,
1423 angle::EntryPoint entryPoint,
1424 ShaderProgramID program,
1425 GLenum programInterface,
1426 GLuint index,
1427 GLsizei bufSize,
1428 const GLsizei *length,
1429 const GLchar *name)
1430 {
1431 if (context->getClientVersion() < ES_3_1)
1432 {
1433 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1434 return false;
1435 }
1436
1437 Program *programObject = GetValidProgram(context, entryPoint, program);
1438 if (programObject == nullptr)
1439 {
1440 return false;
1441 }
1442
1443 if (!ValidateNamedProgramInterface(programInterface))
1444 {
1445 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
1446 return false;
1447 }
1448
1449 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1450 {
1451 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1452 return false;
1453 }
1454
1455 if (bufSize < 0)
1456 {
1457 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
1458 return false;
1459 }
1460
1461 return true;
1462 }
1463
ValidateDispatchCompute(const Context * context,angle::EntryPoint entryPoint,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)1464 bool ValidateDispatchCompute(const Context *context,
1465 angle::EntryPoint entryPoint,
1466 GLuint numGroupsX,
1467 GLuint numGroupsY,
1468 GLuint numGroupsZ)
1469 {
1470 if (context->getClientVersion() < ES_3_1)
1471 {
1472 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1473 return false;
1474 }
1475
1476 const State &state = context->getState();
1477 const ProgramExecutable *executable = state.getProgramExecutable();
1478
1479 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1480 {
1481 context->validationError(entryPoint, GL_INVALID_OPERATION,
1482 kNoActiveProgramWithComputeShader);
1483 return false;
1484 }
1485
1486 const Caps &caps = context->getCaps();
1487 if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
1488 {
1489 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
1490 return false;
1491 }
1492 if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
1493 {
1494 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
1495 return false;
1496 }
1497 if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
1498 {
1499 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
1500 return false;
1501 }
1502
1503 return true;
1504 }
1505
ValidateDispatchComputeIndirect(const Context * context,angle::EntryPoint entryPoint,GLintptr indirect)1506 bool ValidateDispatchComputeIndirect(const Context *context,
1507 angle::EntryPoint entryPoint,
1508 GLintptr indirect)
1509 {
1510 if (context->getClientVersion() < ES_3_1)
1511 {
1512 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1513 return false;
1514 }
1515
1516 const State &state = context->getState();
1517 const ProgramExecutable *executable = state.getProgramExecutable();
1518
1519 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1520 {
1521 context->validationError(entryPoint, GL_INVALID_OPERATION,
1522 kNoActiveProgramWithComputeShader);
1523 return false;
1524 }
1525
1526 if (indirect < 0)
1527 {
1528 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
1529 return false;
1530 }
1531
1532 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1533 {
1534 context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
1535 return false;
1536 }
1537
1538 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
1539 if (!dispatchIndirectBuffer)
1540 {
1541 context->validationError(entryPoint, GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
1542 return false;
1543 }
1544
1545 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1546 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1547 if (!checkedSum.IsValid() ||
1548 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1549 {
1550 context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
1551 return false;
1552 }
1553
1554 return true;
1555 }
1556
ValidateBindImageTexture(const Context * context,angle::EntryPoint entryPoint,GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1557 bool ValidateBindImageTexture(const Context *context,
1558 angle::EntryPoint entryPoint,
1559 GLuint unit,
1560 TextureID texture,
1561 GLint level,
1562 GLboolean layered,
1563 GLint layer,
1564 GLenum access,
1565 GLenum format)
1566 {
1567 if (context->getClientVersion() < ES_3_1)
1568 {
1569 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1570 return false;
1571 }
1572
1573 GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
1574 if (unit >= maxImageUnits)
1575 {
1576 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxImageUnits);
1577 return false;
1578 }
1579
1580 if (level < 0)
1581 {
1582 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel);
1583 return false;
1584 }
1585
1586 if (layer < 0)
1587 {
1588 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer);
1589 return false;
1590 }
1591
1592 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1593 {
1594 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageAccess);
1595 return false;
1596 }
1597
1598 switch (format)
1599 {
1600 case GL_RGBA32F:
1601 case GL_RGBA16F:
1602 case GL_R32F:
1603 case GL_RGBA32UI:
1604 case GL_RGBA16UI:
1605 case GL_RGBA8UI:
1606 case GL_R32UI:
1607 case GL_RGBA32I:
1608 case GL_RGBA16I:
1609 case GL_RGBA8I:
1610 case GL_R32I:
1611 case GL_RGBA8:
1612 case GL_RGBA8_SNORM:
1613 break;
1614 default:
1615 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidImageFormat);
1616 return false;
1617 }
1618
1619 if (texture.value != 0)
1620 {
1621 Texture *tex = context->getTexture(texture);
1622
1623 if (tex == nullptr)
1624 {
1625 context->validationError(entryPoint, GL_INVALID_VALUE, kMissingTextureName);
1626 return false;
1627 }
1628
1629 if (!tex->getImmutableFormat())
1630 {
1631 context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsNotImmutable);
1632 return false;
1633 }
1634 }
1635
1636 return true;
1637 }
1638
ValidateGetProgramResourceLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const GLchar * name)1639 bool ValidateGetProgramResourceLocation(const Context *context,
1640 angle::EntryPoint entryPoint,
1641 ShaderProgramID program,
1642 GLenum programInterface,
1643 const GLchar *name)
1644 {
1645 if (context->getClientVersion() < ES_3_1)
1646 {
1647 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1648 return false;
1649 }
1650
1651 Program *programObject = GetValidProgram(context, entryPoint, program);
1652 if (programObject == nullptr)
1653 {
1654 return false;
1655 }
1656
1657 if (!programObject->isLinked())
1658 {
1659 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
1660 return false;
1661 }
1662
1663 if (!ValidateLocationProgramInterface(programInterface))
1664 {
1665 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
1666 return false;
1667 }
1668 return true;
1669 }
1670
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)1671 bool ValidateGetProgramResourceiv(const Context *context,
1672 angle::EntryPoint entryPoint,
1673 ShaderProgramID program,
1674 GLenum programInterface,
1675 GLuint index,
1676 GLsizei propCount,
1677 const GLenum *props,
1678 GLsizei bufSize,
1679 const GLsizei *length,
1680 const GLint *params)
1681 {
1682 if (context->getClientVersion() < ES_3_1)
1683 {
1684 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1685 return false;
1686 }
1687
1688 Program *programObject = GetValidProgram(context, entryPoint, program);
1689 if (programObject == nullptr)
1690 {
1691 return false;
1692 }
1693 if (!ValidateProgramInterface(programInterface))
1694 {
1695 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
1696 return false;
1697 }
1698 if (propCount <= 0)
1699 {
1700 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPropCount);
1701 return false;
1702 }
1703 if (bufSize < 0)
1704 {
1705 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufSize);
1706 return false;
1707 }
1708 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1709 {
1710 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1711 return false;
1712 }
1713 for (GLsizei i = 0; i < propCount; i++)
1714 {
1715 if (!ValidateProgramResourceProperty(context, entryPoint, props[i]))
1716 {
1717 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1718 return false;
1719 }
1720 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1721 {
1722 context->validationError(entryPoint, GL_INVALID_OPERATION,
1723 kInvalidPropertyForProgramInterface);
1724 return false;
1725 }
1726 }
1727 return true;
1728 }
1729
ValidateGetProgramInterfaceiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1730 bool ValidateGetProgramInterfaceiv(const Context *context,
1731 angle::EntryPoint entryPoint,
1732 ShaderProgramID program,
1733 GLenum programInterface,
1734 GLenum pname,
1735 const GLint *params)
1736 {
1737 if (context->getClientVersion() < ES_3_1)
1738 {
1739 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
1740 return false;
1741 }
1742
1743 Program *programObject = GetValidProgram(context, entryPoint, program);
1744 if (programObject == nullptr)
1745 {
1746 return false;
1747 }
1748
1749 if (!ValidateProgramInterface(programInterface))
1750 {
1751 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
1752 return false;
1753 }
1754
1755 switch (pname)
1756 {
1757 case GL_ACTIVE_RESOURCES:
1758 case GL_MAX_NAME_LENGTH:
1759 case GL_MAX_NUM_ACTIVE_VARIABLES:
1760 break;
1761
1762 default:
1763 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
1764 return false;
1765 }
1766
1767 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1768 {
1769 context->validationError(entryPoint, GL_INVALID_OPERATION, kAtomicCounterResourceName);
1770 return false;
1771 }
1772
1773 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1774 {
1775 switch (programInterface)
1776 {
1777 case GL_ATOMIC_COUNTER_BUFFER:
1778 case GL_SHADER_STORAGE_BLOCK:
1779 case GL_UNIFORM_BLOCK:
1780 break;
1781
1782 default:
1783 context->validationError(entryPoint, GL_INVALID_OPERATION,
1784 kMaxActiveVariablesInterface);
1785 return false;
1786 }
1787 }
1788
1789 return true;
1790 }
1791
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1792 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1793 angle::EntryPoint entryPoint,
1794 ShaderProgramID program,
1795 GLenum programInterface,
1796 GLenum pname,
1797 GLsizei bufSize,
1798 const GLsizei *length,
1799 const GLint *params)
1800 {
1801 UNIMPLEMENTED();
1802 return false;
1803 }
1804
ValidateGenProgramPipelinesBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelines)1805 bool ValidateGenProgramPipelinesBase(const Context *context,
1806 angle::EntryPoint entryPoint,
1807 GLsizei n,
1808 const ProgramPipelineID *pipelines)
1809 {
1810 return ValidateGenOrDelete(context, entryPoint, n);
1811 }
1812
ValidateDeleteProgramPipelinesBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelines)1813 bool ValidateDeleteProgramPipelinesBase(const Context *context,
1814 angle::EntryPoint entryPoint,
1815 GLsizei n,
1816 const ProgramPipelineID *pipelines)
1817 {
1818 return ValidateGenOrDelete(context, entryPoint, n);
1819 }
1820
ValidateBindProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1821 bool ValidateBindProgramPipelineBase(const Context *context,
1822 angle::EntryPoint entryPoint,
1823 ProgramPipelineID pipeline)
1824 {
1825 if (!context->isProgramPipelineGenerated({pipeline}))
1826 {
1827 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
1828 return false;
1829 }
1830
1831 return true;
1832 }
1833
ValidateIsProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1834 bool ValidateIsProgramPipelineBase(const Context *context,
1835 angle::EntryPoint entryPoint,
1836 ProgramPipelineID pipeline)
1837 {
1838 return true;
1839 }
1840
ValidateUseProgramStagesBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1841 bool ValidateUseProgramStagesBase(const Context *context,
1842 angle::EntryPoint entryPoint,
1843 ProgramPipelineID pipeline,
1844 GLbitfield stages,
1845 ShaderProgramID programId)
1846 {
1847 // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
1848 // not the reserved value GL_ALL_SHADER_BITS.
1849 GLbitfield knownShaderBits =
1850 GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1851
1852 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
1853 {
1854 knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
1855 }
1856
1857 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT)
1858 {
1859 knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
1860 knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
1861 }
1862
1863 if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1864 {
1865 context->validationError(entryPoint, GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1866 return false;
1867 }
1868
1869 // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1870 // to glGenProgramPipelines or if such a name has been deleted by a call to
1871 // glDeleteProgramPipelines.
1872 if (!context->isProgramPipelineGenerated({pipeline}))
1873 {
1874 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
1875 return false;
1876 }
1877
1878 // If program is zero, or refers to a program object with no valid shader executable for a given
1879 // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1880 // shader stages.
1881 if (programId.value == 0)
1882 {
1883 return true;
1884 }
1885
1886 Program *program = context->getProgramNoResolveLink(programId);
1887 if (!program)
1888 {
1889 context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist);
1890 return false;
1891 }
1892
1893 // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1894 // with its GL_PROGRAM_SEPARABLE status set.
1895 // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1896 // glDetachShader() was not called.
1897 program->resolveLink(context);
1898 if (!program->isSeparable())
1899 {
1900 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotSeparable);
1901 return false;
1902 }
1903
1904 // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1905 // successfully linked.
1906 if (!program->isLinked())
1907 {
1908 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
1909 return false;
1910 }
1911
1912 return true;
1913 }
1914
ValidateActiveShaderProgramBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,ShaderProgramID programId)1915 bool ValidateActiveShaderProgramBase(const Context *context,
1916 angle::EntryPoint entryPoint,
1917 ProgramPipelineID pipeline,
1918 ShaderProgramID programId)
1919 {
1920 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1921 // call to GenProgramPipelines or if such a name has since been deleted by
1922 // DeleteProgramPipelines.
1923 if (!context->isProgramPipelineGenerated({pipeline}))
1924 {
1925 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
1926 return false;
1927 }
1928
1929 // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1930 // program or shader object.
1931 if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1932 {
1933 context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist);
1934 return false;
1935 }
1936
1937 // An INVALID_OPERATION error is generated if program is the name of a shader object.
1938 if (context->isShader(programId))
1939 {
1940 context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName);
1941 return false;
1942 }
1943
1944 // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1945 // was last linked unsuccessfully. The active program is not modified.
1946 Program *program = context->getProgramNoResolveLink(programId);
1947 if ((programId.value != 0) && !program->isLinked())
1948 {
1949 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
1950 return false;
1951 }
1952
1953 return true;
1954 }
1955
ValidateCreateShaderProgramvBase(const Context * context,angle::EntryPoint entryPoint,ShaderType type,GLsizei count,const GLchar * const * strings)1956 bool ValidateCreateShaderProgramvBase(const Context *context,
1957 angle::EntryPoint entryPoint,
1958 ShaderType type,
1959 GLsizei count,
1960 const GLchar *const *strings)
1961 {
1962 switch (type)
1963 {
1964 case ShaderType::InvalidEnum:
1965 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
1966 return false;
1967 case ShaderType::Vertex:
1968 case ShaderType::Fragment:
1969 case ShaderType::Compute:
1970 break;
1971 case ShaderType::Geometry:
1972 if (!context->getExtensions().geometryShaderAny() &&
1973 context->getClientVersion() < ES_3_2)
1974 {
1975 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
1976 return false;
1977 }
1978 break;
1979 case ShaderType::TessControl:
1980 case ShaderType::TessEvaluation:
1981 if (!context->getExtensions().tessellationShaderEXT &&
1982 context->getClientVersion() < ES_3_2)
1983 {
1984 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
1985 return false;
1986 }
1987 break;
1988 default:
1989 UNREACHABLE();
1990 }
1991
1992 // GL_INVALID_VALUE is generated if count is negative.
1993 if (count < 0)
1994 {
1995 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
1996 return false;
1997 }
1998
1999 return true;
2000 }
2001
ValidateCreateShaderProgramvBase(const Context * context,angle::EntryPoint entryPoint,ShaderType type,GLsizei count,const GLchar ** strings)2002 bool ValidateCreateShaderProgramvBase(const Context *context,
2003 angle::EntryPoint entryPoint,
2004 ShaderType type,
2005 GLsizei count,
2006 const GLchar **strings)
2007 {
2008 const GLchar *const *tmpStrings = strings;
2009 return ValidateCreateShaderProgramvBase(context, entryPoint, type, count, tmpStrings);
2010 }
2011
ValidateGetProgramPipelineivBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLenum pname,const GLint * params)2012 bool ValidateGetProgramPipelineivBase(const Context *context,
2013 angle::EntryPoint entryPoint,
2014 ProgramPipelineID pipeline,
2015 GLenum pname,
2016 const GLint *params)
2017 {
2018 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
2019 // call to GenProgramPipelines or if such a name has since been deleted by
2020 // DeleteProgramPipelines.
2021 if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
2022 {
2023 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
2024 return false;
2025 }
2026
2027 // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
2028 // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
2029 // table 7.1.
2030 switch (pname)
2031 {
2032 case GL_ACTIVE_PROGRAM:
2033 case GL_INFO_LOG_LENGTH:
2034 case GL_VALIDATE_STATUS:
2035 case GL_VERTEX_SHADER:
2036 case GL_FRAGMENT_SHADER:
2037 case GL_COMPUTE_SHADER:
2038 break;
2039 case GL_GEOMETRY_SHADER:
2040 return context->getExtensions().geometryShaderAny() ||
2041 context->getClientVersion() >= ES_3_2;
2042 case GL_TESS_CONTROL_SHADER:
2043 case GL_TESS_EVALUATION_SHADER:
2044 return context->getExtensions().tessellationShaderEXT ||
2045 context->getClientVersion() >= ES_3_2;
2046
2047 default:
2048 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
2049 return false;
2050 }
2051
2052 return true;
2053 }
2054
ValidateValidateProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)2055 bool ValidateValidateProgramPipelineBase(const Context *context,
2056 angle::EntryPoint entryPoint,
2057 ProgramPipelineID pipeline)
2058 {
2059 if (pipeline.value == 0)
2060 {
2061 return false;
2062 }
2063
2064 if (!context->isProgramPipelineGenerated(pipeline))
2065 {
2066 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
2067 return false;
2068 }
2069
2070 return true;
2071 }
2072
ValidateGetProgramPipelineInfoLogBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)2073 bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
2074 angle::EntryPoint entryPoint,
2075 ProgramPipelineID pipeline,
2076 GLsizei bufSize,
2077 const GLsizei *length,
2078 const GLchar *infoLog)
2079 {
2080 if (bufSize < 0)
2081 {
2082 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
2083 return false;
2084 }
2085
2086 if (!context->isProgramPipelineGenerated(pipeline))
2087 {
2088 context->validationError(entryPoint, GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
2089 return false;
2090 }
2091
2092 return true;
2093 }
2094
ValidateActiveShaderProgram(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)2095 bool ValidateActiveShaderProgram(const Context *context,
2096 angle::EntryPoint entryPoint,
2097 ProgramPipelineID pipelinePacked,
2098 ShaderProgramID programPacked)
2099 {
2100 if (context->getClientVersion() < ES_3_1)
2101 {
2102 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2103 return false;
2104 }
2105
2106 return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
2107 }
2108
ValidateBindProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2109 bool ValidateBindProgramPipeline(const Context *context,
2110 angle::EntryPoint entryPoint,
2111 ProgramPipelineID pipelinePacked)
2112 {
2113 if (context->getClientVersion() < ES_3_1)
2114 {
2115 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2116 return false;
2117 }
2118
2119 return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
2120 }
2121
ValidateCreateShaderProgramv(const Context * context,angle::EntryPoint entryPoint,ShaderType typePacked,GLsizei count,const GLchar * const * strings)2122 bool ValidateCreateShaderProgramv(const Context *context,
2123 angle::EntryPoint entryPoint,
2124 ShaderType typePacked,
2125 GLsizei count,
2126 const GLchar *const *strings)
2127 {
2128 if (context->getClientVersion() < ES_3_1)
2129 {
2130 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2131 return false;
2132 }
2133
2134 return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
2135 }
2136
ValidateDeleteProgramPipelines(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)2137 bool ValidateDeleteProgramPipelines(const Context *context,
2138 angle::EntryPoint entryPoint,
2139 GLsizei n,
2140 const ProgramPipelineID *pipelinesPacked)
2141 {
2142 if (context->getClientVersion() < ES_3_1)
2143 {
2144 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2145 return false;
2146 }
2147
2148 return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
2149 }
2150
ValidateGenProgramPipelines(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)2151 bool ValidateGenProgramPipelines(const Context *context,
2152 angle::EntryPoint entryPoint,
2153 GLsizei n,
2154 const ProgramPipelineID *pipelinesPacked)
2155 {
2156 if (context->getClientVersion() < ES_3_1)
2157 {
2158 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2159 return false;
2160 }
2161
2162 return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
2163 }
2164
ValidateGetProgramPipelineInfoLog(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)2165 bool ValidateGetProgramPipelineInfoLog(const Context *context,
2166 angle::EntryPoint entryPoint,
2167 ProgramPipelineID pipelinePacked,
2168 GLsizei bufSize,
2169 const GLsizei *length,
2170 const GLchar *infoLog)
2171 {
2172 if (context->getClientVersion() < ES_3_1)
2173 {
2174 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2175 return false;
2176 }
2177
2178 return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
2179 length, infoLog);
2180 }
2181
ValidateGetProgramPipelineiv(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)2182 bool ValidateGetProgramPipelineiv(const Context *context,
2183 angle::EntryPoint entryPoint,
2184 ProgramPipelineID pipelinePacked,
2185 GLenum pname,
2186 const GLint *params)
2187 {
2188 if (context->getClientVersion() < ES_3_1)
2189 {
2190 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2191 return false;
2192 }
2193
2194 return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
2195 }
2196
ValidateIsProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2197 bool ValidateIsProgramPipeline(const Context *context,
2198 angle::EntryPoint entryPoint,
2199 ProgramPipelineID pipelinePacked)
2200 {
2201 if (context->getClientVersion() < ES_3_1)
2202 {
2203 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2204 return false;
2205 }
2206
2207 return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
2208 }
2209
ValidateProgramUniform1f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)2210 bool ValidateProgramUniform1f(const Context *context,
2211 angle::EntryPoint entryPoint,
2212 ShaderProgramID programPacked,
2213 UniformLocation locationPacked,
2214 GLfloat v0)
2215 {
2216 if (context->getClientVersion() < ES_3_1)
2217 {
2218 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2219 return false;
2220 }
2221
2222 return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
2223 }
2224
ValidateProgramUniform1fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2225 bool ValidateProgramUniform1fv(const Context *context,
2226 angle::EntryPoint entryPoint,
2227 ShaderProgramID programPacked,
2228 UniformLocation locationPacked,
2229 GLsizei count,
2230 const GLfloat *value)
2231 {
2232 if (context->getClientVersion() < ES_3_1)
2233 {
2234 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2235 return false;
2236 }
2237
2238 return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
2239 value);
2240 }
2241
ValidateProgramUniform1i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)2242 bool ValidateProgramUniform1i(const Context *context,
2243 angle::EntryPoint entryPoint,
2244 ShaderProgramID programPacked,
2245 UniformLocation locationPacked,
2246 GLint v0)
2247 {
2248 if (context->getClientVersion() < ES_3_1)
2249 {
2250 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2251 return false;
2252 }
2253
2254 return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
2255 }
2256
ValidateProgramUniform1iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2257 bool ValidateProgramUniform1iv(const Context *context,
2258 angle::EntryPoint entryPoint,
2259 ShaderProgramID programPacked,
2260 UniformLocation locationPacked,
2261 GLsizei count,
2262 const GLint *value)
2263 {
2264 if (context->getClientVersion() < ES_3_1)
2265 {
2266 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2267 return false;
2268 }
2269
2270 return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
2271 value);
2272 }
2273
ValidateProgramUniform1ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)2274 bool ValidateProgramUniform1ui(const Context *context,
2275 angle::EntryPoint entryPoint,
2276 ShaderProgramID programPacked,
2277 UniformLocation locationPacked,
2278 GLuint v0)
2279 {
2280 if (context->getClientVersion() < ES_3_1)
2281 {
2282 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2283 return false;
2284 }
2285
2286 return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
2287 }
2288
ValidateProgramUniform1uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2289 bool ValidateProgramUniform1uiv(const Context *context,
2290 angle::EntryPoint entryPoint,
2291 ShaderProgramID programPacked,
2292 UniformLocation locationPacked,
2293 GLsizei count,
2294 const GLuint *value)
2295 {
2296 if (context->getClientVersion() < ES_3_1)
2297 {
2298 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2299 return false;
2300 }
2301
2302 return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
2303 value);
2304 }
2305
ValidateProgramUniform2f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)2306 bool ValidateProgramUniform2f(const Context *context,
2307 angle::EntryPoint entryPoint,
2308 ShaderProgramID programPacked,
2309 UniformLocation locationPacked,
2310 GLfloat v0,
2311 GLfloat v1)
2312 {
2313 if (context->getClientVersion() < ES_3_1)
2314 {
2315 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2316 return false;
2317 }
2318
2319 return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
2320 }
2321
ValidateProgramUniform2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2322 bool ValidateProgramUniform2fv(const Context *context,
2323 angle::EntryPoint entryPoint,
2324 ShaderProgramID programPacked,
2325 UniformLocation locationPacked,
2326 GLsizei count,
2327 const GLfloat *value)
2328 {
2329 if (context->getClientVersion() < ES_3_1)
2330 {
2331 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2332 return false;
2333 }
2334
2335 return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
2336 value);
2337 }
2338
ValidateProgramUniform2i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)2339 bool ValidateProgramUniform2i(const Context *context,
2340 angle::EntryPoint entryPoint,
2341 ShaderProgramID programPacked,
2342 UniformLocation locationPacked,
2343 GLint v0,
2344 GLint v1)
2345 {
2346 if (context->getClientVersion() < ES_3_1)
2347 {
2348 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2349 return false;
2350 }
2351
2352 return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
2353 }
2354
ValidateProgramUniform2iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2355 bool ValidateProgramUniform2iv(const Context *context,
2356 angle::EntryPoint entryPoint,
2357 ShaderProgramID programPacked,
2358 UniformLocation locationPacked,
2359 GLsizei count,
2360 const GLint *value)
2361 {
2362 if (context->getClientVersion() < ES_3_1)
2363 {
2364 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2365 return false;
2366 }
2367
2368 return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
2369 value);
2370 }
2371
ValidateProgramUniform2ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)2372 bool ValidateProgramUniform2ui(const Context *context,
2373 angle::EntryPoint entryPoint,
2374 ShaderProgramID programPacked,
2375 UniformLocation locationPacked,
2376 GLuint v0,
2377 GLuint v1)
2378 {
2379 if (context->getClientVersion() < ES_3_1)
2380 {
2381 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2382 return false;
2383 }
2384
2385 return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
2386 v1);
2387 }
2388
ValidateProgramUniform2uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2389 bool ValidateProgramUniform2uiv(const Context *context,
2390 angle::EntryPoint entryPoint,
2391 ShaderProgramID programPacked,
2392 UniformLocation locationPacked,
2393 GLsizei count,
2394 const GLuint *value)
2395 {
2396 if (context->getClientVersion() < ES_3_1)
2397 {
2398 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2399 return false;
2400 }
2401
2402 return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
2403 value);
2404 }
2405
ValidateProgramUniform3f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)2406 bool ValidateProgramUniform3f(const Context *context,
2407 angle::EntryPoint entryPoint,
2408 ShaderProgramID programPacked,
2409 UniformLocation locationPacked,
2410 GLfloat v0,
2411 GLfloat v1,
2412 GLfloat v2)
2413 {
2414 if (context->getClientVersion() < ES_3_1)
2415 {
2416 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2417 return false;
2418 }
2419
2420 return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2421 v2);
2422 }
2423
ValidateProgramUniform3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2424 bool ValidateProgramUniform3fv(const Context *context,
2425 angle::EntryPoint entryPoint,
2426 ShaderProgramID programPacked,
2427 UniformLocation locationPacked,
2428 GLsizei count,
2429 const GLfloat *value)
2430 {
2431 if (context->getClientVersion() < ES_3_1)
2432 {
2433 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2434 return false;
2435 }
2436
2437 return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
2438 value);
2439 }
2440
ValidateProgramUniform3i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)2441 bool ValidateProgramUniform3i(const Context *context,
2442 angle::EntryPoint entryPoint,
2443 ShaderProgramID programPacked,
2444 UniformLocation locationPacked,
2445 GLint v0,
2446 GLint v1,
2447 GLint v2)
2448 {
2449 if (context->getClientVersion() < ES_3_1)
2450 {
2451 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2452 return false;
2453 }
2454
2455 return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2456 v2);
2457 }
2458
ValidateProgramUniform3iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2459 bool ValidateProgramUniform3iv(const Context *context,
2460 angle::EntryPoint entryPoint,
2461 ShaderProgramID programPacked,
2462 UniformLocation locationPacked,
2463 GLsizei count,
2464 const GLint *value)
2465 {
2466 if (context->getClientVersion() < ES_3_1)
2467 {
2468 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2469 return false;
2470 }
2471
2472 return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
2473 value);
2474 }
2475
ValidateProgramUniform3ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)2476 bool ValidateProgramUniform3ui(const Context *context,
2477 angle::EntryPoint entryPoint,
2478 ShaderProgramID programPacked,
2479 UniformLocation locationPacked,
2480 GLuint v0,
2481 GLuint v1,
2482 GLuint v2)
2483 {
2484 if (context->getClientVersion() < ES_3_1)
2485 {
2486 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2487 return false;
2488 }
2489
2490 return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2491 v2);
2492 }
2493
ValidateProgramUniform3uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2494 bool ValidateProgramUniform3uiv(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 ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
2508 value);
2509 }
2510
ValidateProgramUniform4f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)2511 bool ValidateProgramUniform4f(const Context *context,
2512 angle::EntryPoint entryPoint,
2513 ShaderProgramID programPacked,
2514 UniformLocation locationPacked,
2515 GLfloat v0,
2516 GLfloat v1,
2517 GLfloat v2,
2518 GLfloat v3)
2519 {
2520 if (context->getClientVersion() < ES_3_1)
2521 {
2522 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2523 return false;
2524 }
2525
2526 return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2527 v2, v3);
2528 }
2529
ValidateProgramUniform4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2530 bool ValidateProgramUniform4fv(const Context *context,
2531 angle::EntryPoint entryPoint,
2532 ShaderProgramID programPacked,
2533 UniformLocation locationPacked,
2534 GLsizei count,
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 ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
2544 value);
2545 }
2546
ValidateProgramUniform4i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)2547 bool ValidateProgramUniform4i(const Context *context,
2548 angle::EntryPoint entryPoint,
2549 ShaderProgramID programPacked,
2550 UniformLocation locationPacked,
2551 GLint v0,
2552 GLint v1,
2553 GLint v2,
2554 GLint v3)
2555 {
2556 if (context->getClientVersion() < ES_3_1)
2557 {
2558 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2559 return false;
2560 }
2561
2562 return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2563 v2, v3);
2564 }
2565
ValidateProgramUniform4iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2566 bool ValidateProgramUniform4iv(const Context *context,
2567 angle::EntryPoint entryPoint,
2568 ShaderProgramID programPacked,
2569 UniformLocation locationPacked,
2570 GLsizei count,
2571 const GLint *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 ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
2580 value);
2581 }
2582
ValidateProgramUniform4ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)2583 bool ValidateProgramUniform4ui(const Context *context,
2584 angle::EntryPoint entryPoint,
2585 ShaderProgramID programPacked,
2586 UniformLocation locationPacked,
2587 GLuint v0,
2588 GLuint v1,
2589 GLuint v2,
2590 GLuint v3)
2591 {
2592 if (context->getClientVersion() < ES_3_1)
2593 {
2594 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2595 return false;
2596 }
2597
2598 return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2599 v2, v3);
2600 }
2601
ValidateProgramUniform4uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2602 bool ValidateProgramUniform4uiv(const Context *context,
2603 angle::EntryPoint entryPoint,
2604 ShaderProgramID programPacked,
2605 UniformLocation locationPacked,
2606 GLsizei count,
2607 const GLuint *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 ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
2616 value);
2617 }
2618
ValidateProgramUniformMatrix2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2619 bool ValidateProgramUniformMatrix2fv(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 ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
2634 count, transpose, value);
2635 }
2636
ValidateProgramUniformMatrix2x3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2637 bool ValidateProgramUniformMatrix2x3fv(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 ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
2652 count, transpose, value);
2653 }
2654
ValidateProgramUniformMatrix2x4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2655 bool ValidateProgramUniformMatrix2x4fv(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 ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
2670 count, transpose, value);
2671 }
2672
ValidateProgramUniformMatrix3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2673 bool ValidateProgramUniformMatrix3fv(const Context *context,
2674 angle::EntryPoint entryPoint,
2675 ShaderProgramID programPacked,
2676 UniformLocation locationPacked,
2677 GLsizei count,
2678 GLboolean transpose,
2679 const GLfloat *value)
2680 {
2681 if (context->getClientVersion() < ES_3_1)
2682 {
2683 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2684 return false;
2685 }
2686
2687 return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
2688 count, transpose, value);
2689 }
2690
ValidateProgramUniformMatrix3x2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2691 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
2692 angle::EntryPoint entryPoint,
2693 ShaderProgramID programPacked,
2694 UniformLocation locationPacked,
2695 GLsizei count,
2696 GLboolean transpose,
2697 const GLfloat *value)
2698 {
2699 if (context->getClientVersion() < ES_3_1)
2700 {
2701 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2702 return false;
2703 }
2704
2705 return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
2706 count, transpose, value);
2707 }
2708
ValidateProgramUniformMatrix3x4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2709 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
2710 angle::EntryPoint entryPoint,
2711 ShaderProgramID programPacked,
2712 UniformLocation locationPacked,
2713 GLsizei count,
2714 GLboolean transpose,
2715 const GLfloat *value)
2716 {
2717 if (context->getClientVersion() < ES_3_1)
2718 {
2719 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2720 return false;
2721 }
2722
2723 return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
2724 count, transpose, value);
2725 }
2726
ValidateProgramUniformMatrix4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2727 bool ValidateProgramUniformMatrix4fv(const Context *context,
2728 angle::EntryPoint entryPoint,
2729 ShaderProgramID programPacked,
2730 UniformLocation locationPacked,
2731 GLsizei count,
2732 GLboolean transpose,
2733 const GLfloat *value)
2734 {
2735 if (context->getClientVersion() < ES_3_1)
2736 {
2737 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2738 return false;
2739 }
2740
2741 return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
2742 count, transpose, value);
2743 }
2744
ValidateProgramUniformMatrix4x2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2745 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
2746 angle::EntryPoint entryPoint,
2747 ShaderProgramID programPacked,
2748 UniformLocation locationPacked,
2749 GLsizei count,
2750 GLboolean transpose,
2751 const GLfloat *value)
2752 {
2753 if (context->getClientVersion() < ES_3_1)
2754 {
2755 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2756 return false;
2757 }
2758
2759 return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
2760 count, transpose, value);
2761 }
2762
ValidateProgramUniformMatrix4x3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2763 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
2764 angle::EntryPoint entryPoint,
2765 ShaderProgramID programPacked,
2766 UniformLocation locationPacked,
2767 GLsizei count,
2768 GLboolean transpose,
2769 const GLfloat *value)
2770 {
2771 if (context->getClientVersion() < ES_3_1)
2772 {
2773 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2774 return false;
2775 }
2776
2777 return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
2778 count, transpose, value);
2779 }
2780
ValidateUseProgramStages(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)2781 bool ValidateUseProgramStages(const Context *context,
2782 angle::EntryPoint entryPoint,
2783 ProgramPipelineID pipelinePacked,
2784 GLbitfield stages,
2785 ShaderProgramID programPacked)
2786 {
2787 if (context->getClientVersion() < ES_3_1)
2788 {
2789 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2790 return false;
2791 }
2792
2793 return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
2794 }
2795
ValidateValidateProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2796 bool ValidateValidateProgramPipeline(const Context *context,
2797 angle::EntryPoint entryPoint,
2798 ProgramPipelineID pipelinePacked)
2799 {
2800 if (context->getClientVersion() < ES_3_1)
2801 {
2802 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2803 return false;
2804 }
2805
2806 return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
2807 }
2808
ValidateMemoryBarrier(const Context * context,angle::EntryPoint entryPoint,GLbitfield barriers)2809 bool ValidateMemoryBarrier(const Context *context,
2810 angle::EntryPoint entryPoint,
2811 GLbitfield barriers)
2812 {
2813 if (context->getClientVersion() < ES_3_1)
2814 {
2815 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2816 return false;
2817 }
2818
2819 if (barriers == GL_ALL_BARRIER_BITS)
2820 {
2821 return true;
2822 }
2823
2824 GLbitfield supported_barrier_bits =
2825 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
2826 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
2827 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
2828 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
2829 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
2830
2831 if (context->getExtensions().bufferStorageEXT)
2832 {
2833 supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
2834 }
2835
2836 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2837 {
2838 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2839 return false;
2840 }
2841
2842 return true;
2843 }
2844
ValidateMemoryBarrierByRegion(const Context * context,angle::EntryPoint entryPoint,GLbitfield barriers)2845 bool ValidateMemoryBarrierByRegion(const Context *context,
2846 angle::EntryPoint entryPoint,
2847 GLbitfield barriers)
2848 {
2849 if (context->getClientVersion() < ES_3_1)
2850 {
2851 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2852 return false;
2853 }
2854
2855 if (barriers == GL_ALL_BARRIER_BITS)
2856 {
2857 return true;
2858 }
2859
2860 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
2861 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
2862 GL_SHADER_STORAGE_BARRIER_BIT |
2863 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
2864 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2865 {
2866 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2867 return false;
2868 }
2869
2870 return true;
2871 }
2872
ValidateSampleMaski(const Context * context,angle::EntryPoint entryPoint,GLuint maskNumber,GLbitfield mask)2873 bool ValidateSampleMaski(const Context *context,
2874 angle::EntryPoint entryPoint,
2875 GLuint maskNumber,
2876 GLbitfield mask)
2877 {
2878 if (context->getClientVersion() < ES_3_1)
2879 {
2880 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2881 return false;
2882 }
2883
2884 return ValidateSampleMaskiBase(context, entryPoint, maskNumber, mask);
2885 }
2886
ValidateMinSampleShadingOES(const Context * context,angle::EntryPoint entryPoint,GLfloat value)2887 bool ValidateMinSampleShadingOES(const Context *context,
2888 angle::EntryPoint entryPoint,
2889 GLfloat value)
2890 {
2891 if (!context->getExtensions().sampleShadingOES)
2892 {
2893 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
2894 return false;
2895 }
2896
2897 return true;
2898 }
2899
ValidateFramebufferTextureCommon(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2900 bool ValidateFramebufferTextureCommon(const Context *context,
2901 angle::EntryPoint entryPoint,
2902 GLenum target,
2903 GLenum attachment,
2904 TextureID texture,
2905 GLint level)
2906 {
2907 if (texture.value != 0)
2908 {
2909 Texture *tex = context->getTexture(texture);
2910
2911 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2912 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2913 // We put this validation before ValidateFramebufferTextureBase because it is an
2914 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2915 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2916 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2917 // existing texture object of type matching textarget.
2918 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2919 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2920 // three-dimensional or two-dimensional array texture.
2921 if (tex == nullptr)
2922 {
2923 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName);
2924 return false;
2925 }
2926
2927 if (!ValidMipLevel(context, tex->getType(), level))
2928 {
2929 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
2930 return false;
2931 }
2932
2933 // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2934 // If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero.
2935 if (tex->getType() == TextureType::_2DMultisample && level != 0)
2936 {
2937 context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero);
2938 return false;
2939 }
2940
2941 // [OES_texture_storage_multisample_2d_array] Section 9.2.2 "Attaching Images to Framebuffer
2942 // Objects"
2943 // If texture is a two-dimensional multisample array texture, then level must be zero.
2944 if (context->getExtensions().textureStorageMultisample2dArrayOES &&
2945 tex->getType() == TextureType::_2DMultisampleArray && level != 0)
2946 {
2947 context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero);
2948 return false;
2949 }
2950 }
2951
2952 if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
2953 {
2954 return false;
2955 }
2956
2957 return true;
2958 }
2959
ValidateFramebufferTextureEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2960 bool ValidateFramebufferTextureEXT(const Context *context,
2961 angle::EntryPoint entryPoint,
2962 GLenum target,
2963 GLenum attachment,
2964 TextureID texture,
2965 GLint level)
2966 {
2967 if (!context->getExtensions().geometryShaderEXT)
2968 {
2969 context->validationError(entryPoint, GL_INVALID_OPERATION,
2970 kGeometryShaderExtensionNotEnabled);
2971 return false;
2972 }
2973
2974 return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
2975 level);
2976 }
2977
ValidateFramebufferTextureOES(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2978 bool ValidateFramebufferTextureOES(const Context *context,
2979 angle::EntryPoint entryPoint,
2980 GLenum target,
2981 GLenum attachment,
2982 TextureID texture,
2983 GLint level)
2984 {
2985 if (!context->getExtensions().geometryShaderOES)
2986 {
2987 context->validationError(entryPoint, GL_INVALID_OPERATION,
2988 kGeometryShaderExtensionNotEnabled);
2989 return false;
2990 }
2991
2992 return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
2993 level);
2994 }
2995
2996 // 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)2997 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2998 angle::EntryPoint entryPoint,
2999 TextureType target,
3000 GLsizei samples,
3001 GLenum sizedinternalformat,
3002 GLsizei width,
3003 GLsizei height,
3004 GLsizei depth,
3005 GLboolean fixedsamplelocations)
3006 {
3007 if (!context->getExtensions().textureStorageMultisample2dArrayOES)
3008 {
3009 context->validationError(entryPoint, GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
3010 return false;
3011 }
3012
3013 if (target != TextureType::_2DMultisampleArray)
3014 {
3015 context->validationError(entryPoint, GL_INVALID_ENUM,
3016 kTargetMustBeTexture2DMultisampleArrayOES);
3017 return false;
3018 }
3019
3020 if (width < 1 || height < 1 || depth < 1)
3021 {
3022 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
3023 return false;
3024 }
3025
3026 if (depth > context->getCaps().maxArrayTextureLayers)
3027 {
3028 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureDepthOutOfRange);
3029 return false;
3030 }
3031
3032 return ValidateTexStorageMultisample(context, entryPoint, target, samples, sizedinternalformat,
3033 width, height);
3034 }
3035
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)3036 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
3037 angle::EntryPoint entryPoint,
3038 TextureType target,
3039 GLsizei samples,
3040 GLenum internalFormat,
3041 GLsizei width,
3042 GLsizei height,
3043 GLsizei depth,
3044 GLboolean fixedSampleLocations,
3045 MemoryObjectID memory,
3046 GLuint64 offset)
3047 {
3048 if (!context->getExtensions().memoryObjectEXT)
3049 {
3050 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3051 return false;
3052 }
3053
3054 UNIMPLEMENTED();
3055 return false;
3056 }
3057
ValidateGetProgramResourceLocationIndexEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const char * name)3058 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
3059 angle::EntryPoint entryPoint,
3060 ShaderProgramID program,
3061 GLenum programInterface,
3062 const char *name)
3063 {
3064 if (!context->getExtensions().blendFuncExtendedEXT)
3065 {
3066 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3067 return false;
3068 }
3069 if (context->getClientVersion() < ES_3_1)
3070 {
3071 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
3072 return false;
3073 }
3074 if (programInterface != GL_PROGRAM_OUTPUT)
3075 {
3076 context->validationError(entryPoint, GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
3077 return false;
3078 }
3079 Program *programObject = GetValidProgram(context, entryPoint, program);
3080 if (!programObject)
3081 {
3082 return false;
3083 }
3084 if (!programObject->isLinked())
3085 {
3086 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
3087 return false;
3088 }
3089 return true;
3090 }
3091
3092 // GL_OES_texture_buffer
ValidateTexBufferOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3093 bool ValidateTexBufferOES(const Context *context,
3094 angle::EntryPoint entryPoint,
3095 TextureType target,
3096 GLenum internalformat,
3097 BufferID bufferPacked)
3098 {
3099 if (!context->getExtensions().textureBufferOES)
3100 {
3101 context->validationError(entryPoint, GL_INVALID_OPERATION,
3102 kTextureBufferExtensionNotAvailable);
3103 return false;
3104 }
3105
3106 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3107 }
3108
ValidateTexBufferRangeOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3109 bool ValidateTexBufferRangeOES(const Context *context,
3110 angle::EntryPoint entryPoint,
3111 TextureType target,
3112 GLenum internalformat,
3113 BufferID bufferPacked,
3114 GLintptr offset,
3115 GLsizeiptr size)
3116 {
3117 if (!context->getExtensions().textureBufferOES)
3118 {
3119 context->validationError(entryPoint, GL_INVALID_OPERATION,
3120 kTextureBufferExtensionNotAvailable);
3121 return false;
3122 }
3123
3124 return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
3125 offset, size);
3126 }
3127
3128 // GL_EXT_texture_buffer
ValidateTexBufferEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3129 bool ValidateTexBufferEXT(const Context *context,
3130 angle::EntryPoint entryPoint,
3131 TextureType target,
3132 GLenum internalformat,
3133 BufferID bufferPacked)
3134 {
3135 if (!context->getExtensions().textureBufferEXT)
3136 {
3137 context->validationError(entryPoint, GL_INVALID_OPERATION,
3138 kTextureBufferExtensionNotAvailable);
3139 return false;
3140 }
3141
3142 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3143 }
3144
ValidateTexBufferRangeEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3145 bool ValidateTexBufferRangeEXT(const Context *context,
3146 angle::EntryPoint entryPoint,
3147 TextureType target,
3148 GLenum internalformat,
3149 BufferID bufferPacked,
3150 GLintptr offset,
3151 GLsizeiptr size)
3152 {
3153 if (!context->getExtensions().textureBufferEXT)
3154 {
3155 context->validationError(entryPoint, GL_INVALID_OPERATION,
3156 kTextureBufferExtensionNotAvailable);
3157 return false;
3158 }
3159
3160 return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
3161 offset, size);
3162 }
3163
ValidateTexBufferBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3164 bool ValidateTexBufferBase(const Context *context,
3165 angle::EntryPoint entryPoint,
3166 TextureType target,
3167 GLenum internalformat,
3168 BufferID bufferPacked)
3169 {
3170 if (target != TextureType::Buffer)
3171 {
3172 context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferTarget);
3173 return false;
3174 }
3175
3176 switch (internalformat)
3177 {
3178 case GL_R8:
3179 case GL_R16F:
3180 case GL_R32F:
3181 case GL_R8I:
3182 case GL_R16I:
3183 case GL_R32I:
3184 case GL_R8UI:
3185 case GL_R16UI:
3186 case GL_R32UI:
3187 case GL_RG8:
3188 case GL_RG16F:
3189 case GL_RG32F:
3190 case GL_RG8I:
3191 case GL_RG16I:
3192 case GL_RG32I:
3193 case GL_RG8UI:
3194 case GL_RG16UI:
3195 case GL_RG32UI:
3196 case GL_RGB32F:
3197 case GL_RGB32I:
3198 case GL_RGB32UI:
3199 case GL_RGBA8:
3200 case GL_RGBA16F:
3201 case GL_RGBA32F:
3202 case GL_RGBA8I:
3203 case GL_RGBA16I:
3204 case GL_RGBA32I:
3205 case GL_RGBA8UI:
3206 case GL_RGBA16UI:
3207 case GL_RGBA32UI:
3208 break;
3209
3210 default:
3211 context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferInternalFormat);
3212 return false;
3213 }
3214
3215 if (bufferPacked.value != 0)
3216 {
3217 if (!context->isBufferGenerated(bufferPacked))
3218 {
3219 context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
3220 return false;
3221 }
3222 }
3223
3224 return true;
3225 }
3226
ValidateTexBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3227 bool ValidateTexBufferRangeBase(const Context *context,
3228 angle::EntryPoint entryPoint,
3229 TextureType target,
3230 GLenum internalformat,
3231 BufferID bufferPacked,
3232 GLintptr offset,
3233 GLsizeiptr size)
3234 {
3235 const Caps &caps = context->getCaps();
3236
3237 if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
3238 {
3239 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
3240 return false;
3241 }
3242 if (size <= 0)
3243 {
3244 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSize);
3245 return false;
3246 }
3247 const Buffer *buffer = context->getBuffer(bufferPacked);
3248
3249 if (!buffer)
3250 {
3251 context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
3252 return false;
3253 }
3254
3255 if (offset + size > buffer->getSize())
3256 {
3257 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSizeOffset);
3258 return false;
3259 }
3260
3261 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3262 }
3263
3264 } // namespace gl
3265