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/validationES3_autogen.h"
19
20 #include "common/utilities.h"
21
22 using namespace angle;
23
24 namespace gl
25 {
26 using namespace err;
27
28 namespace
29 {
30
ValidateNamedProgramInterface(GLenum programInterface)31 bool ValidateNamedProgramInterface(GLenum programInterface)
32 {
33 switch (programInterface)
34 {
35 case GL_UNIFORM:
36 case GL_UNIFORM_BLOCK:
37 case GL_PROGRAM_INPUT:
38 case GL_PROGRAM_OUTPUT:
39 case GL_TRANSFORM_FEEDBACK_VARYING:
40 case GL_BUFFER_VARIABLE:
41 case GL_SHADER_STORAGE_BLOCK:
42 return true;
43 default:
44 return false;
45 }
46 }
47
ValidateLocationProgramInterface(GLenum programInterface)48 bool ValidateLocationProgramInterface(GLenum programInterface)
49 {
50 switch (programInterface)
51 {
52 case GL_UNIFORM:
53 case GL_PROGRAM_INPUT:
54 case GL_PROGRAM_OUTPUT:
55 return true;
56 default:
57 return false;
58 }
59 }
60
ValidateProgramInterface(GLenum programInterface)61 bool ValidateProgramInterface(GLenum programInterface)
62 {
63 return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
64 ValidateNamedProgramInterface(programInterface));
65 }
66
ValidateProgramResourceProperty(const Context * context,GLenum prop)67 bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
68 {
69 ASSERT(context);
70 switch (prop)
71 {
72 case GL_ACTIVE_VARIABLES:
73 case GL_BUFFER_BINDING:
74 case GL_NUM_ACTIVE_VARIABLES:
75
76 case GL_ARRAY_SIZE:
77
78 case GL_ARRAY_STRIDE:
79 case GL_BLOCK_INDEX:
80 case GL_IS_ROW_MAJOR:
81 case GL_MATRIX_STRIDE:
82
83 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
84
85 case GL_BUFFER_DATA_SIZE:
86
87 case GL_LOCATION:
88
89 case GL_NAME_LENGTH:
90
91 case GL_OFFSET:
92
93 case GL_REFERENCED_BY_VERTEX_SHADER:
94 case GL_REFERENCED_BY_FRAGMENT_SHADER:
95 case GL_REFERENCED_BY_COMPUTE_SHADER:
96
97 case GL_TOP_LEVEL_ARRAY_SIZE:
98 case GL_TOP_LEVEL_ARRAY_STRIDE:
99
100 case GL_TYPE:
101 return true;
102
103 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
104 return context->getExtensions().geometryShader;
105
106 case GL_LOCATION_INDEX_EXT:
107 return context->getExtensions().blendFuncExtended;
108
109 default:
110 return false;
111 }
112 }
113
114 // GLES 3.10 spec: Page 82 -- Table 7.2
ValidateProgramResourcePropertyByInterface(GLenum prop,GLenum programInterface)115 bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
116 {
117 switch (prop)
118 {
119 case GL_ACTIVE_VARIABLES:
120 case GL_BUFFER_BINDING:
121 case GL_NUM_ACTIVE_VARIABLES:
122 {
123 switch (programInterface)
124 {
125 case GL_ATOMIC_COUNTER_BUFFER:
126 case GL_SHADER_STORAGE_BLOCK:
127 case GL_UNIFORM_BLOCK:
128 return true;
129 default:
130 return false;
131 }
132 }
133
134 case GL_ARRAY_SIZE:
135 {
136 switch (programInterface)
137 {
138 case GL_BUFFER_VARIABLE:
139 case GL_PROGRAM_INPUT:
140 case GL_PROGRAM_OUTPUT:
141 case GL_TRANSFORM_FEEDBACK_VARYING:
142 case GL_UNIFORM:
143 return true;
144 default:
145 return false;
146 }
147 }
148
149 case GL_ARRAY_STRIDE:
150 case GL_BLOCK_INDEX:
151 case GL_IS_ROW_MAJOR:
152 case GL_MATRIX_STRIDE:
153 {
154 switch (programInterface)
155 {
156 case GL_BUFFER_VARIABLE:
157 case GL_UNIFORM:
158 return true;
159 default:
160 return false;
161 }
162 }
163
164 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
165 {
166 if (programInterface == GL_UNIFORM)
167 {
168 return true;
169 }
170 return false;
171 }
172
173 case GL_BUFFER_DATA_SIZE:
174 {
175 switch (programInterface)
176 {
177 case GL_ATOMIC_COUNTER_BUFFER:
178 case GL_SHADER_STORAGE_BLOCK:
179 case GL_UNIFORM_BLOCK:
180 return true;
181 default:
182 return false;
183 }
184 }
185
186 case GL_LOCATION:
187 {
188 return ValidateLocationProgramInterface(programInterface);
189 }
190
191 case GL_LOCATION_INDEX_EXT:
192 {
193 // EXT_blend_func_extended
194 return (programInterface == GL_PROGRAM_OUTPUT);
195 }
196
197 case GL_NAME_LENGTH:
198 {
199 return ValidateNamedProgramInterface(programInterface);
200 }
201
202 case GL_OFFSET:
203 {
204 switch (programInterface)
205 {
206 case GL_BUFFER_VARIABLE:
207 case GL_UNIFORM:
208 return true;
209 default:
210 return false;
211 }
212 }
213
214 case GL_REFERENCED_BY_VERTEX_SHADER:
215 case GL_REFERENCED_BY_FRAGMENT_SHADER:
216 case GL_REFERENCED_BY_COMPUTE_SHADER:
217 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
218 {
219 switch (programInterface)
220 {
221 case GL_ATOMIC_COUNTER_BUFFER:
222 case GL_BUFFER_VARIABLE:
223 case GL_PROGRAM_INPUT:
224 case GL_PROGRAM_OUTPUT:
225 case GL_SHADER_STORAGE_BLOCK:
226 case GL_UNIFORM:
227 case GL_UNIFORM_BLOCK:
228 return true;
229 default:
230 return false;
231 }
232 }
233
234 case GL_TOP_LEVEL_ARRAY_SIZE:
235 case GL_TOP_LEVEL_ARRAY_STRIDE:
236 {
237 if (programInterface == GL_BUFFER_VARIABLE)
238 {
239 return true;
240 }
241 return false;
242 }
243
244 case GL_TYPE:
245 {
246 switch (programInterface)
247 {
248 case GL_BUFFER_VARIABLE:
249 case GL_PROGRAM_INPUT:
250 case GL_PROGRAM_OUTPUT:
251 case GL_TRANSFORM_FEEDBACK_VARYING:
252 case GL_UNIFORM:
253 return true;
254 default:
255 return false;
256 }
257 }
258
259 default:
260 return false;
261 }
262 }
263
ValidateProgramResourceIndex(const Program * programObject,GLenum programInterface,GLuint index)264 bool ValidateProgramResourceIndex(const Program *programObject,
265 GLenum programInterface,
266 GLuint index)
267 {
268 switch (programInterface)
269 {
270 case GL_PROGRAM_INPUT:
271 return (index <
272 static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
273
274 case GL_PROGRAM_OUTPUT:
275 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
276
277 case GL_UNIFORM:
278 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
279
280 case GL_BUFFER_VARIABLE:
281 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
282
283 case GL_SHADER_STORAGE_BLOCK:
284 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
285
286 case GL_UNIFORM_BLOCK:
287 return (index < programObject->getActiveUniformBlockCount());
288
289 case GL_ATOMIC_COUNTER_BUFFER:
290 return (index < programObject->getActiveAtomicCounterBufferCount());
291
292 case GL_TRANSFORM_FEEDBACK_VARYING:
293 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
294
295 default:
296 UNREACHABLE();
297 return false;
298 }
299 }
300
ValidateProgramUniform(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count)301 bool ValidateProgramUniform(const Context *context,
302 GLenum valueType,
303 ShaderProgramID program,
304 UniformLocation location,
305 GLsizei count)
306 {
307 // Check for ES31 program uniform entry points
308 if (context->getClientVersion() < Version(3, 1))
309 {
310 context->validationError(GL_INVALID_OPERATION, kES31Required);
311 return false;
312 }
313
314 const LinkedUniform *uniform = nullptr;
315 Program *programObject = GetValidProgram(context, program);
316 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
317 ValidateUniformValue(context, valueType, uniform->type);
318 }
319
ValidateProgramUniformMatrix(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose)320 bool ValidateProgramUniformMatrix(const Context *context,
321 GLenum valueType,
322 ShaderProgramID program,
323 UniformLocation location,
324 GLsizei count,
325 GLboolean transpose)
326 {
327 // Check for ES31 program uniform entry points
328 if (context->getClientVersion() < Version(3, 1))
329 {
330 context->validationError(GL_INVALID_OPERATION, kES31Required);
331 return false;
332 }
333
334 const LinkedUniform *uniform = nullptr;
335 Program *programObject = GetValidProgram(context, program);
336 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
337 ValidateUniformMatrixValue(context, valueType, uniform->type);
338 }
339
ValidateVertexAttribFormatCommon(const Context * context,GLuint relativeOffset)340 bool ValidateVertexAttribFormatCommon(const Context *context, GLuint relativeOffset)
341 {
342 if (context->getClientVersion() < ES_3_1)
343 {
344 context->validationError(GL_INVALID_OPERATION, kES31Required);
345 return false;
346 }
347
348 const Caps &caps = context->getCaps();
349 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
350 {
351 context->validationError(GL_INVALID_VALUE, kRelativeOffsetTooLarge);
352 return false;
353 }
354
355 // [OpenGL ES 3.1] Section 10.3.1 page 243:
356 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
357 if (context->getState().getVertexArrayId().value == 0)
358 {
359 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
360 return false;
361 }
362
363 return true;
364 }
365
366 } // anonymous namespace
367
ValidateGetBooleani_v(const Context * context,GLenum target,GLuint index,const GLboolean * data)368 bool ValidateGetBooleani_v(const Context *context,
369 GLenum target,
370 GLuint index,
371 const GLboolean *data)
372 {
373 if (context->getClientVersion() < ES_3_1)
374 {
375 context->validationError(GL_INVALID_OPERATION, kES31Required);
376 return false;
377 }
378
379 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
380 {
381 return false;
382 }
383
384 return true;
385 }
386
ValidateGetBooleani_vRobustANGLE(const Context * context,GLenum target,GLuint index,GLsizei bufSize,const GLsizei * length,const GLboolean * data)387 bool ValidateGetBooleani_vRobustANGLE(const Context *context,
388 GLenum target,
389 GLuint index,
390 GLsizei bufSize,
391 const GLsizei *length,
392 const GLboolean *data)
393 {
394 if (context->getClientVersion() < ES_3_1)
395 {
396 context->validationError(GL_INVALID_OPERATION, kES31Required);
397 return false;
398 }
399
400 if (!ValidateRobustEntryPoint(context, bufSize))
401 {
402 return false;
403 }
404
405 GLsizei numParams = 0;
406
407 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
408 {
409 return false;
410 }
411
412 if (!ValidateRobustBufferSize(context, bufSize, numParams))
413 {
414 return false;
415 }
416
417 SetRobustLengthParam(length, numParams);
418 return true;
419 }
420
ValidateDrawIndirectBase(const Context * context,PrimitiveMode mode,const void * indirect)421 bool ValidateDrawIndirectBase(const Context *context, PrimitiveMode mode, const void *indirect)
422 {
423 if (context->getClientVersion() < ES_3_1)
424 {
425 context->validationError(GL_INVALID_OPERATION, kES31Required);
426 return false;
427 }
428
429 // Here the third parameter 1 is only to pass the count validation.
430 if (!ValidateDrawBase(context, mode))
431 {
432 return false;
433 }
434
435 const State &state = context->getState();
436
437 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
438 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
439 if (state.getVertexArrayId().value == 0)
440 {
441 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
442 return false;
443 }
444
445 if (context->getStateCache().hasAnyActiveClientAttrib())
446 {
447 context->validationError(GL_INVALID_OPERATION, kClientDataInVertexArray);
448 return false;
449 }
450
451 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
452 if (!drawIndirectBuffer)
453 {
454 context->validationError(GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
455 return false;
456 }
457
458 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
459 // machine units, of uint.
460 GLint64 offset = reinterpret_cast<GLint64>(indirect);
461 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
462 {
463 context->validationError(GL_INVALID_VALUE, kInvalidIndirectOffset);
464 return false;
465 }
466
467 return true;
468 }
469
ValidateDrawArraysIndirect(const Context * context,PrimitiveMode mode,const void * indirect)470 bool ValidateDrawArraysIndirect(const Context *context, PrimitiveMode mode, const void *indirect)
471 {
472 const State &state = context->getState();
473 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
474 if (curTransformFeedback && curTransformFeedback->isActive() &&
475 !curTransformFeedback->isPaused())
476 {
477 // EXT_geometry_shader allows transform feedback to work with all draw commands.
478 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
479 if (context->getExtensions().geometryShader)
480 {
481 if (!ValidateTransformFeedbackPrimitiveMode(
482 context, curTransformFeedback->getPrimitiveMode(), mode))
483 {
484 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
485 return false;
486 }
487 }
488 else
489 {
490 // An INVALID_OPERATION error is generated if transform feedback is active and not
491 // paused.
492 context->validationError(GL_INVALID_OPERATION,
493 kUnsupportedDrawModeForTransformFeedback);
494 return false;
495 }
496 }
497
498 if (!ValidateDrawIndirectBase(context, mode, indirect))
499 return false;
500
501 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
502 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
503 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
504 // which's size is 4 * sizeof(uint).
505 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
506 if (!checkedSum.IsValid() ||
507 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
508 {
509 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
510 return false;
511 }
512
513 return true;
514 }
515
ValidateDrawElementsIndirect(const Context * context,PrimitiveMode mode,DrawElementsType type,const void * indirect)516 bool ValidateDrawElementsIndirect(const Context *context,
517 PrimitiveMode mode,
518 DrawElementsType type,
519 const void *indirect)
520 {
521 if (!ValidateDrawElementsBase(context, mode, type))
522 {
523 return false;
524 }
525
526 const State &state = context->getState();
527 const VertexArray *vao = state.getVertexArray();
528 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
529 if (!elementArrayBuffer)
530 {
531 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
532 return false;
533 }
534
535 if (!ValidateDrawIndirectBase(context, mode, indirect))
536 return false;
537
538 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
539 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
540 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
541 // which's size is 5 * sizeof(uint).
542 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
543 if (!checkedSum.IsValid() ||
544 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
545 {
546 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
547 return false;
548 }
549
550 return true;
551 }
552
ValidateProgramUniform1i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0)553 bool ValidateProgramUniform1i(const Context *context,
554 ShaderProgramID program,
555 UniformLocation location,
556 GLint v0)
557 {
558 return ValidateProgramUniform1iv(context, program, location, 1, &v0);
559 }
560
ValidateProgramUniform2i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1)561 bool ValidateProgramUniform2i(const Context *context,
562 ShaderProgramID program,
563 UniformLocation location,
564 GLint v0,
565 GLint v1)
566 {
567 GLint xy[2] = {v0, v1};
568 return ValidateProgramUniform2iv(context, program, location, 1, xy);
569 }
570
ValidateProgramUniform3i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2)571 bool ValidateProgramUniform3i(const Context *context,
572 ShaderProgramID program,
573 UniformLocation location,
574 GLint v0,
575 GLint v1,
576 GLint v2)
577 {
578 GLint xyz[3] = {v0, v1, v2};
579 return ValidateProgramUniform3iv(context, program, location, 1, xyz);
580 }
581
ValidateProgramUniform4i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2,GLint v3)582 bool ValidateProgramUniform4i(const Context *context,
583 ShaderProgramID program,
584 UniformLocation location,
585 GLint v0,
586 GLint v1,
587 GLint v2,
588 GLint v3)
589 {
590 GLint xyzw[4] = {v0, v1, v2, v3};
591 return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
592 }
593
ValidateProgramUniform1ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0)594 bool ValidateProgramUniform1ui(const Context *context,
595 ShaderProgramID program,
596 UniformLocation location,
597 GLuint v0)
598 {
599 return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
600 }
601
ValidateProgramUniform2ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1)602 bool ValidateProgramUniform2ui(const Context *context,
603 ShaderProgramID program,
604 UniformLocation location,
605 GLuint v0,
606 GLuint v1)
607 {
608 GLuint xy[2] = {v0, v1};
609 return ValidateProgramUniform2uiv(context, program, location, 1, xy);
610 }
611
ValidateProgramUniform3ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)612 bool ValidateProgramUniform3ui(const Context *context,
613 ShaderProgramID program,
614 UniformLocation location,
615 GLuint v0,
616 GLuint v1,
617 GLuint v2)
618 {
619 GLuint xyz[3] = {v0, v1, v2};
620 return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
621 }
622
ValidateProgramUniform4ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)623 bool ValidateProgramUniform4ui(const Context *context,
624 ShaderProgramID program,
625 UniformLocation location,
626 GLuint v0,
627 GLuint v1,
628 GLuint v2,
629 GLuint v3)
630 {
631 GLuint xyzw[4] = {v0, v1, v2, v3};
632 return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
633 }
634
ValidateProgramUniform1f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0)635 bool ValidateProgramUniform1f(const Context *context,
636 ShaderProgramID program,
637 UniformLocation location,
638 GLfloat v0)
639 {
640 return ValidateProgramUniform1fv(context, program, location, 1, &v0);
641 }
642
ValidateProgramUniform2f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1)643 bool ValidateProgramUniform2f(const Context *context,
644 ShaderProgramID program,
645 UniformLocation location,
646 GLfloat v0,
647 GLfloat v1)
648 {
649 GLfloat xy[2] = {v0, v1};
650 return ValidateProgramUniform2fv(context, program, location, 1, xy);
651 }
652
ValidateProgramUniform3f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2)653 bool ValidateProgramUniform3f(const Context *context,
654 ShaderProgramID program,
655 UniformLocation location,
656 GLfloat v0,
657 GLfloat v1,
658 GLfloat v2)
659 {
660 GLfloat xyz[3] = {v0, v1, v2};
661 return ValidateProgramUniform3fv(context, program, location, 1, xyz);
662 }
663
ValidateProgramUniform4f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)664 bool ValidateProgramUniform4f(const Context *context,
665 ShaderProgramID program,
666 UniformLocation location,
667 GLfloat v0,
668 GLfloat v1,
669 GLfloat v2,
670 GLfloat v3)
671 {
672 GLfloat xyzw[4] = {v0, v1, v2, v3};
673 return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
674 }
675
ValidateProgramUniform1iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)676 bool ValidateProgramUniform1iv(const Context *context,
677 ShaderProgramID program,
678 UniformLocation location,
679 GLsizei count,
680 const GLint *value)
681 {
682 // Check for ES31 program uniform entry points
683 if (context->getClientVersion() < Version(3, 1))
684 {
685 context->validationError(GL_INVALID_OPERATION, kES31Required);
686 return false;
687 }
688
689 const LinkedUniform *uniform = nullptr;
690 Program *programObject = GetValidProgram(context, program);
691 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
692 ValidateUniform1ivValue(context, uniform->type, count, value);
693 }
694
ValidateProgramUniform2iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)695 bool ValidateProgramUniform2iv(const Context *context,
696 ShaderProgramID program,
697 UniformLocation location,
698 GLsizei count,
699 const GLint *value)
700 {
701 return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
702 }
703
ValidateProgramUniform3iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)704 bool ValidateProgramUniform3iv(const Context *context,
705 ShaderProgramID program,
706 UniformLocation location,
707 GLsizei count,
708 const GLint *value)
709 {
710 return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
711 }
712
ValidateProgramUniform4iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)713 bool ValidateProgramUniform4iv(const Context *context,
714 ShaderProgramID program,
715 UniformLocation location,
716 GLsizei count,
717 const GLint *value)
718 {
719 return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
720 }
721
ValidateProgramUniform1uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)722 bool ValidateProgramUniform1uiv(const Context *context,
723 ShaderProgramID program,
724 UniformLocation location,
725 GLsizei count,
726 const GLuint *value)
727 {
728 return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
729 }
730
ValidateProgramUniform2uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)731 bool ValidateProgramUniform2uiv(const Context *context,
732 ShaderProgramID program,
733 UniformLocation location,
734 GLsizei count,
735 const GLuint *value)
736 {
737 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
738 }
739
ValidateProgramUniform3uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)740 bool ValidateProgramUniform3uiv(const Context *context,
741 ShaderProgramID program,
742 UniformLocation location,
743 GLsizei count,
744 const GLuint *value)
745 {
746 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
747 }
748
ValidateProgramUniform4uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)749 bool ValidateProgramUniform4uiv(const Context *context,
750 ShaderProgramID program,
751 UniformLocation location,
752 GLsizei count,
753 const GLuint *value)
754 {
755 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
756 }
757
ValidateProgramUniform1fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)758 bool ValidateProgramUniform1fv(const Context *context,
759 ShaderProgramID program,
760 UniformLocation location,
761 GLsizei count,
762 const GLfloat *value)
763 {
764 return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
765 }
766
ValidateProgramUniform2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)767 bool ValidateProgramUniform2fv(const Context *context,
768 ShaderProgramID program,
769 UniformLocation location,
770 GLsizei count,
771 const GLfloat *value)
772 {
773 return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
774 }
775
ValidateProgramUniform3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)776 bool ValidateProgramUniform3fv(const Context *context,
777 ShaderProgramID program,
778 UniformLocation location,
779 GLsizei count,
780 const GLfloat *value)
781 {
782 return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
783 }
784
ValidateProgramUniform4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)785 bool ValidateProgramUniform4fv(const Context *context,
786 ShaderProgramID program,
787 UniformLocation location,
788 GLsizei count,
789 const GLfloat *value)
790 {
791 return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
792 }
793
ValidateProgramUniformMatrix2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)794 bool ValidateProgramUniformMatrix2fv(const Context *context,
795 ShaderProgramID program,
796 UniformLocation location,
797 GLsizei count,
798 GLboolean transpose,
799 const GLfloat *value)
800 {
801 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
802 transpose);
803 }
804
ValidateProgramUniformMatrix3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)805 bool ValidateProgramUniformMatrix3fv(const Context *context,
806 ShaderProgramID program,
807 UniformLocation location,
808 GLsizei count,
809 GLboolean transpose,
810 const GLfloat *value)
811 {
812 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
813 transpose);
814 }
815
ValidateProgramUniformMatrix4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)816 bool ValidateProgramUniformMatrix4fv(const Context *context,
817 ShaderProgramID program,
818 UniformLocation location,
819 GLsizei count,
820 GLboolean transpose,
821 const GLfloat *value)
822 {
823 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
824 transpose);
825 }
826
ValidateProgramUniformMatrix2x3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)827 bool ValidateProgramUniformMatrix2x3fv(const Context *context,
828 ShaderProgramID program,
829 UniformLocation location,
830 GLsizei count,
831 GLboolean transpose,
832 const GLfloat *value)
833 {
834 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
835 transpose);
836 }
837
ValidateProgramUniformMatrix3x2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)838 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
839 ShaderProgramID program,
840 UniformLocation location,
841 GLsizei count,
842 GLboolean transpose,
843 const GLfloat *value)
844 {
845 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
846 transpose);
847 }
848
ValidateProgramUniformMatrix2x4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)849 bool ValidateProgramUniformMatrix2x4fv(const Context *context,
850 ShaderProgramID program,
851 UniformLocation location,
852 GLsizei count,
853 GLboolean transpose,
854 const GLfloat *value)
855 {
856 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
857 transpose);
858 }
859
ValidateProgramUniformMatrix4x2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)860 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
861 ShaderProgramID program,
862 UniformLocation location,
863 GLsizei count,
864 GLboolean transpose,
865 const GLfloat *value)
866 {
867 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
868 transpose);
869 }
870
ValidateProgramUniformMatrix3x4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)871 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
872 ShaderProgramID program,
873 UniformLocation location,
874 GLsizei count,
875 GLboolean transpose,
876 const GLfloat *value)
877 {
878 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
879 transpose);
880 }
881
ValidateProgramUniformMatrix4x3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)882 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
883 ShaderProgramID program,
884 UniformLocation location,
885 GLsizei count,
886 GLboolean transpose,
887 const GLfloat *value)
888 {
889 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
890 transpose);
891 }
892
ValidateGetTexLevelParameterfv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLfloat * params)893 bool ValidateGetTexLevelParameterfv(const Context *context,
894 TextureTarget target,
895 GLint level,
896 GLenum pname,
897 const GLfloat *params)
898 {
899 if (context->getClientVersion() < ES_3_1)
900 {
901 context->validationError(GL_INVALID_OPERATION, kES31Required);
902 return false;
903 }
904
905 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
906 }
907
ValidateGetTexLevelParameterfvRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)908 bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
909 TextureTarget target,
910 GLint level,
911 GLenum pname,
912 GLsizei bufSize,
913 const GLsizei *length,
914 const GLfloat *params)
915 {
916 UNIMPLEMENTED();
917 return false;
918 }
919
ValidateGetTexLevelParameteriv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLint * params)920 bool ValidateGetTexLevelParameteriv(const Context *context,
921 TextureTarget target,
922 GLint level,
923 GLenum pname,
924 const GLint *params)
925 {
926 if (context->getClientVersion() < ES_3_1)
927 {
928 context->validationError(GL_INVALID_OPERATION, kES31Required);
929 return false;
930 }
931
932 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
933 }
934
ValidateGetTexLevelParameterivRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)935 bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
936 TextureTarget target,
937 GLint level,
938 GLenum pname,
939 GLsizei bufSize,
940 const GLsizei *length,
941 const GLint *params)
942 {
943 UNIMPLEMENTED();
944 return false;
945 }
946
ValidateTexStorage2DMultisample(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations)947 bool ValidateTexStorage2DMultisample(const Context *context,
948 TextureType target,
949 GLsizei samples,
950 GLenum internalFormat,
951 GLsizei width,
952 GLsizei height,
953 GLboolean fixedSampleLocations)
954 {
955 if (context->getClientVersion() < ES_3_1)
956 {
957 context->validationError(GL_INVALID_OPERATION, kES31Required);
958 return false;
959 }
960
961 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
962 height);
963 }
964
ValidateTexStorageMem2DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)965 bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
966 TextureType target,
967 GLsizei samples,
968 GLenum internalFormat,
969 GLsizei width,
970 GLsizei height,
971 GLboolean fixedSampleLocations,
972 MemoryObjectID memory,
973 GLuint64 offset)
974 {
975 if (!context->getExtensions().memoryObject)
976 {
977 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
978 return false;
979 }
980
981 UNIMPLEMENTED();
982 return false;
983 }
984
ValidateGetMultisamplefv(const Context * context,GLenum pname,GLuint index,const GLfloat * val)985 bool ValidateGetMultisamplefv(const Context *context,
986 GLenum pname,
987 GLuint index,
988 const GLfloat *val)
989 {
990 if (context->getClientVersion() < ES_3_1)
991 {
992 context->validationError(GL_INVALID_OPERATION, kES31Required);
993 return false;
994 }
995
996 return ValidateGetMultisamplefvBase(context, pname, index, val);
997 }
998
ValidateGetMultisamplefvRobustANGLE(const Context * context,GLenum pname,GLuint index,GLsizei bufSize,const GLsizei * length,const GLfloat * val)999 bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
1000 GLenum pname,
1001 GLuint index,
1002 GLsizei bufSize,
1003 const GLsizei *length,
1004 const GLfloat *val)
1005 {
1006 UNIMPLEMENTED();
1007 return false;
1008 }
1009
ValidateFramebufferParameteri(const Context * context,GLenum target,GLenum pname,GLint param)1010 bool ValidateFramebufferParameteri(const Context *context, GLenum target, GLenum pname, GLint param)
1011 {
1012 if (context->getClientVersion() < ES_3_1)
1013 {
1014 context->validationError(GL_INVALID_OPERATION, kES31Required);
1015 return false;
1016 }
1017
1018 if (!ValidFramebufferTarget(context, target))
1019 {
1020 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1021 return false;
1022 }
1023
1024 switch (pname)
1025 {
1026 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1027 {
1028 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1029 if (param < 0 || param > maxWidth)
1030 {
1031 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferWidth);
1032 return false;
1033 }
1034 break;
1035 }
1036 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1037 {
1038 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1039 if (param < 0 || param > maxHeight)
1040 {
1041 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferHeight);
1042 return false;
1043 }
1044 break;
1045 }
1046 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1047 {
1048 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1049 if (param < 0 || param > maxSamples)
1050 {
1051 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferSamples);
1052 return false;
1053 }
1054 break;
1055 }
1056 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1057 {
1058 break;
1059 }
1060 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1061 {
1062 if (!context->getExtensions().geometryShader)
1063 {
1064 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1065 return false;
1066 }
1067 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1068 if (param < 0 || param > maxLayers)
1069 {
1070 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferLayer);
1071 return false;
1072 }
1073 break;
1074 }
1075 default:
1076 {
1077 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1078 return false;
1079 }
1080 }
1081
1082 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1083 ASSERT(framebuffer);
1084 if (framebuffer->isDefault())
1085 {
1086 context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1087 return false;
1088 }
1089 return true;
1090 }
1091
ValidateGetFramebufferParameteriv(const Context * context,GLenum target,GLenum pname,const GLint * params)1092 bool ValidateGetFramebufferParameteriv(const Context *context,
1093 GLenum target,
1094 GLenum pname,
1095 const GLint *params)
1096 {
1097 if (context->getClientVersion() < ES_3_1)
1098 {
1099 context->validationError(GL_INVALID_OPERATION, kES31Required);
1100 return false;
1101 }
1102
1103 if (!ValidFramebufferTarget(context, target))
1104 {
1105 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1106 return false;
1107 }
1108
1109 switch (pname)
1110 {
1111 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1112 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1113 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1114 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1115 break;
1116 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1117 if (!context->getExtensions().geometryShader)
1118 {
1119 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1120 return false;
1121 }
1122 break;
1123 default:
1124 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1125 return false;
1126 }
1127
1128 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1129 ASSERT(framebuffer);
1130
1131 if (framebuffer->isDefault())
1132 {
1133 context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1134 return false;
1135 }
1136 return true;
1137 }
1138
ValidateGetFramebufferParameterivRobustANGLE(const Context * context,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1139 bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
1140 GLenum target,
1141 GLenum pname,
1142 GLsizei bufSize,
1143 const GLsizei *length,
1144 const GLint *params)
1145 {
1146 UNIMPLEMENTED();
1147 return false;
1148 }
1149
ValidateGetProgramResourceIndex(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1150 bool ValidateGetProgramResourceIndex(const Context *context,
1151 ShaderProgramID program,
1152 GLenum programInterface,
1153 const GLchar *name)
1154 {
1155 if (context->getClientVersion() < ES_3_1)
1156 {
1157 context->validationError(GL_INVALID_OPERATION, kES31Required);
1158 return false;
1159 }
1160
1161 Program *programObject = GetValidProgram(context, program);
1162 if (programObject == nullptr)
1163 {
1164 return false;
1165 }
1166
1167 if (!ValidateNamedProgramInterface(programInterface))
1168 {
1169 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1170 return false;
1171 }
1172
1173 return true;
1174 }
1175
ValidateBindVertexBuffer(const Context * context,GLuint bindingIndex,BufferID buffer,GLintptr offset,GLsizei stride)1176 bool ValidateBindVertexBuffer(const Context *context,
1177 GLuint bindingIndex,
1178 BufferID buffer,
1179 GLintptr offset,
1180 GLsizei stride)
1181 {
1182 if (context->getClientVersion() < ES_3_1)
1183 {
1184 context->validationError(GL_INVALID_OPERATION, kES31Required);
1185 return false;
1186 }
1187
1188 if (!context->isBufferGenerated(buffer))
1189 {
1190 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1191 return false;
1192 }
1193
1194 const Caps &caps = context->getCaps();
1195 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1196 {
1197 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1198 return false;
1199 }
1200
1201 if (offset < 0)
1202 {
1203 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1204 return false;
1205 }
1206
1207 if (stride < 0 || stride > caps.maxVertexAttribStride)
1208 {
1209 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
1210 return false;
1211 }
1212
1213 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1214 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1215 if (context->getState().getVertexArrayId().value == 0)
1216 {
1217 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1218 return false;
1219 }
1220
1221 return true;
1222 }
1223
ValidateVertexBindingDivisor(const Context * context,GLuint bindingIndex,GLuint divisor)1224 bool ValidateVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
1225 {
1226 if (context->getClientVersion() < ES_3_1)
1227 {
1228 context->validationError(GL_INVALID_OPERATION, kES31Required);
1229 return false;
1230 }
1231
1232 const Caps &caps = context->getCaps();
1233 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1234 {
1235 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1236 return false;
1237 }
1238
1239 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1240 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1241 if (context->getState().getVertexArrayId().value == 0)
1242 {
1243 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1244 return false;
1245 }
1246
1247 return true;
1248 }
1249
ValidateVertexAttribFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeoffset)1250 bool ValidateVertexAttribFormat(const Context *context,
1251 GLuint attribindex,
1252 GLint size,
1253 VertexAttribType type,
1254 GLboolean normalized,
1255 GLuint relativeoffset)
1256 {
1257 if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1258 {
1259 return false;
1260 }
1261
1262 return ValidateFloatVertexFormat(context, attribindex, size, type);
1263 }
1264
ValidateVertexAttribIFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLuint relativeoffset)1265 bool ValidateVertexAttribIFormat(const Context *context,
1266 GLuint attribindex,
1267 GLint size,
1268 VertexAttribType type,
1269 GLuint relativeoffset)
1270 {
1271 if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1272 {
1273 return false;
1274 }
1275
1276 return ValidateIntegerVertexFormat(context, attribindex, size, type);
1277 }
1278
ValidateVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)1279 bool ValidateVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
1280 {
1281 if (context->getClientVersion() < ES_3_1)
1282 {
1283 context->validationError(GL_INVALID_OPERATION, kES31Required);
1284 return false;
1285 }
1286
1287 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1288 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1289 if (context->getState().getVertexArrayId().value == 0)
1290 {
1291 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1292 return false;
1293 }
1294
1295 const Caps &caps = context->getCaps();
1296 if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
1297 {
1298 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
1299 return false;
1300 }
1301
1302 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1303 {
1304 context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1305 return false;
1306 }
1307
1308 return true;
1309 }
1310
ValidateGetProgramResourceName(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,const GLsizei * length,const GLchar * name)1311 bool ValidateGetProgramResourceName(const Context *context,
1312 ShaderProgramID program,
1313 GLenum programInterface,
1314 GLuint index,
1315 GLsizei bufSize,
1316 const GLsizei *length,
1317 const GLchar *name)
1318 {
1319 if (context->getClientVersion() < ES_3_1)
1320 {
1321 context->validationError(GL_INVALID_OPERATION, kES31Required);
1322 return false;
1323 }
1324
1325 Program *programObject = GetValidProgram(context, program);
1326 if (programObject == nullptr)
1327 {
1328 return false;
1329 }
1330
1331 if (!ValidateNamedProgramInterface(programInterface))
1332 {
1333 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1334 return false;
1335 }
1336
1337 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1338 {
1339 context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1340 return false;
1341 }
1342
1343 if (bufSize < 0)
1344 {
1345 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1346 return false;
1347 }
1348
1349 return true;
1350 }
1351
ValidateDispatchCompute(const Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)1352 bool ValidateDispatchCompute(const Context *context,
1353 GLuint numGroupsX,
1354 GLuint numGroupsY,
1355 GLuint numGroupsZ)
1356 {
1357 if (context->getClientVersion() < ES_3_1)
1358 {
1359 context->validationError(GL_INVALID_OPERATION, kES31Required);
1360 return false;
1361 }
1362
1363 const State &state = context->getState();
1364 const ProgramExecutable *executable = state.getProgramExecutable();
1365
1366 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1367 {
1368 context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1369 return false;
1370 }
1371
1372 const Caps &caps = context->getCaps();
1373 if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
1374 {
1375 context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
1376 return false;
1377 }
1378 if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
1379 {
1380 context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
1381 return false;
1382 }
1383 if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
1384 {
1385 context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
1386 return false;
1387 }
1388
1389 return true;
1390 }
1391
ValidateDispatchComputeIndirect(const Context * context,GLintptr indirect)1392 bool ValidateDispatchComputeIndirect(const Context *context, GLintptr indirect)
1393 {
1394 if (context->getClientVersion() < ES_3_1)
1395 {
1396 context->validationError(GL_INVALID_OPERATION, kES31Required);
1397 return false;
1398 }
1399
1400 const State &state = context->getState();
1401 const ProgramExecutable *executable = state.getProgramExecutable();
1402
1403 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1404 {
1405 context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1406 return false;
1407 }
1408
1409 if (indirect < 0)
1410 {
1411 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1412 return false;
1413 }
1414
1415 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1416 {
1417 context->validationError(GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
1418 return false;
1419 }
1420
1421 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
1422 if (!dispatchIndirectBuffer)
1423 {
1424 context->validationError(GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
1425 return false;
1426 }
1427
1428 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1429 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1430 if (!checkedSum.IsValid() ||
1431 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1432 {
1433 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
1434 return false;
1435 }
1436
1437 return true;
1438 }
1439
ValidateBindImageTexture(const Context * context,GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1440 bool ValidateBindImageTexture(const Context *context,
1441 GLuint unit,
1442 TextureID texture,
1443 GLint level,
1444 GLboolean layered,
1445 GLint layer,
1446 GLenum access,
1447 GLenum format)
1448 {
1449 GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
1450 if (unit >= maxImageUnits)
1451 {
1452 context->validationError(GL_INVALID_VALUE, kExceedsMaxImageUnits);
1453 return false;
1454 }
1455
1456 if (level < 0)
1457 {
1458 context->validationError(GL_INVALID_VALUE, kNegativeLevel);
1459 return false;
1460 }
1461
1462 if (layer < 0)
1463 {
1464 context->validationError(GL_INVALID_VALUE, kNegativeLayer);
1465 return false;
1466 }
1467
1468 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1469 {
1470 context->validationError(GL_INVALID_ENUM, kInvalidImageAccess);
1471 return false;
1472 }
1473
1474 switch (format)
1475 {
1476 case GL_RGBA32F:
1477 case GL_RGBA16F:
1478 case GL_R32F:
1479 case GL_RGBA32UI:
1480 case GL_RGBA16UI:
1481 case GL_RGBA8UI:
1482 case GL_R32UI:
1483 case GL_RGBA32I:
1484 case GL_RGBA16I:
1485 case GL_RGBA8I:
1486 case GL_R32I:
1487 case GL_RGBA8:
1488 case GL_RGBA8_SNORM:
1489 break;
1490 default:
1491 context->validationError(GL_INVALID_VALUE, kInvalidImageFormat);
1492 return false;
1493 }
1494
1495 if (texture.value != 0)
1496 {
1497 Texture *tex = context->getTexture(texture);
1498
1499 if (tex == nullptr)
1500 {
1501 context->validationError(GL_INVALID_VALUE, kMissingTextureName);
1502 return false;
1503 }
1504
1505 if (!tex->getImmutableFormat())
1506 {
1507 context->validationError(GL_INVALID_OPERATION, kTextureIsNotImmutable);
1508 return false;
1509 }
1510 }
1511
1512 return true;
1513 }
1514
ValidateGetProgramResourceLocation(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1515 bool ValidateGetProgramResourceLocation(const Context *context,
1516 ShaderProgramID program,
1517 GLenum programInterface,
1518 const GLchar *name)
1519 {
1520 if (context->getClientVersion() < ES_3_1)
1521 {
1522 context->validationError(GL_INVALID_OPERATION, kES31Required);
1523 return false;
1524 }
1525
1526 Program *programObject = GetValidProgram(context, program);
1527 if (programObject == nullptr)
1528 {
1529 return false;
1530 }
1531
1532 if (!programObject->isLinked())
1533 {
1534 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1535 return false;
1536 }
1537
1538 if (!ValidateLocationProgramInterface(programInterface))
1539 {
1540 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1541 return false;
1542 }
1543 return true;
1544 }
1545
ValidateGetProgramResourceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,const GLsizei * length,const GLint * params)1546 bool ValidateGetProgramResourceiv(const Context *context,
1547 ShaderProgramID program,
1548 GLenum programInterface,
1549 GLuint index,
1550 GLsizei propCount,
1551 const GLenum *props,
1552 GLsizei bufSize,
1553 const GLsizei *length,
1554 const GLint *params)
1555 {
1556 if (context->getClientVersion() < ES_3_1)
1557 {
1558 context->validationError(GL_INVALID_OPERATION, kES31Required);
1559 return false;
1560 }
1561
1562 Program *programObject = GetValidProgram(context, program);
1563 if (programObject == nullptr)
1564 {
1565 return false;
1566 }
1567 if (!ValidateProgramInterface(programInterface))
1568 {
1569 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1570 return false;
1571 }
1572 if (propCount <= 0)
1573 {
1574 context->validationError(GL_INVALID_VALUE, kInvalidPropCount);
1575 return false;
1576 }
1577 if (bufSize < 0)
1578 {
1579 context->validationError(GL_INVALID_VALUE, kNegativeBufSize);
1580 return false;
1581 }
1582 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1583 {
1584 context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1585 return false;
1586 }
1587 for (GLsizei i = 0; i < propCount; i++)
1588 {
1589 if (!ValidateProgramResourceProperty(context, props[i]))
1590 {
1591 context->validationError(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1592 return false;
1593 }
1594 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1595 {
1596 context->validationError(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
1597 return false;
1598 }
1599 }
1600 return true;
1601 }
1602
ValidateGetProgramInterfaceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1603 bool ValidateGetProgramInterfaceiv(const Context *context,
1604 ShaderProgramID program,
1605 GLenum programInterface,
1606 GLenum pname,
1607 const GLint *params)
1608 {
1609 if (context->getClientVersion() < ES_3_1)
1610 {
1611 context->validationError(GL_INVALID_OPERATION, kES31Required);
1612 return false;
1613 }
1614
1615 Program *programObject = GetValidProgram(context, program);
1616 if (programObject == nullptr)
1617 {
1618 return false;
1619 }
1620
1621 if (!ValidateProgramInterface(programInterface))
1622 {
1623 context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1624 return false;
1625 }
1626
1627 switch (pname)
1628 {
1629 case GL_ACTIVE_RESOURCES:
1630 case GL_MAX_NAME_LENGTH:
1631 case GL_MAX_NUM_ACTIVE_VARIABLES:
1632 break;
1633
1634 default:
1635 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1636 return false;
1637 }
1638
1639 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1640 {
1641 context->validationError(GL_INVALID_OPERATION, kAtomicCounterResourceName);
1642 return false;
1643 }
1644
1645 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1646 {
1647 switch (programInterface)
1648 {
1649 case GL_ATOMIC_COUNTER_BUFFER:
1650 case GL_SHADER_STORAGE_BLOCK:
1651 case GL_UNIFORM_BLOCK:
1652 break;
1653
1654 default:
1655 context->validationError(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
1656 return false;
1657 }
1658 }
1659
1660 return true;
1661 }
1662
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1663 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1664 ShaderProgramID program,
1665 GLenum programInterface,
1666 GLenum pname,
1667 GLsizei bufSize,
1668 const GLsizei *length,
1669 const GLint *params)
1670 {
1671 UNIMPLEMENTED();
1672 return false;
1673 }
1674
ValidateGenOrDeleteES31(const Context * context,GLint n)1675 static bool ValidateGenOrDeleteES31(const Context *context, GLint n)
1676 {
1677 if (context->getClientVersion() < ES_3_1)
1678 {
1679 context->validationError(GL_INVALID_OPERATION, kES31Required);
1680 return false;
1681 }
1682
1683 return ValidateGenOrDelete(context, n);
1684 }
1685
ValidateGenProgramPipelines(const Context * context,GLint n,const ProgramPipelineID * pipelines)1686 bool ValidateGenProgramPipelines(const Context *context,
1687 GLint n,
1688 const ProgramPipelineID *pipelines)
1689 {
1690 return ValidateGenOrDeleteES31(context, n);
1691 }
1692
ValidateDeleteProgramPipelines(const Context * context,GLint n,const ProgramPipelineID * pipelines)1693 bool ValidateDeleteProgramPipelines(const Context *context,
1694 GLint n,
1695 const ProgramPipelineID *pipelines)
1696 {
1697 return ValidateGenOrDeleteES31(context, n);
1698 }
1699
ValidateBindProgramPipeline(const Context * context,ProgramPipelineID pipeline)1700 bool ValidateBindProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1701 {
1702 if (context->getClientVersion() < ES_3_1)
1703 {
1704 context->validationError(GL_INVALID_OPERATION, kES31Required);
1705 return false;
1706 }
1707
1708 if (!context->isProgramPipelineGenerated({pipeline}))
1709 {
1710 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1711 return false;
1712 }
1713
1714 return true;
1715 }
1716
ValidateIsProgramPipeline(const Context * context,ProgramPipelineID pipeline)1717 bool ValidateIsProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1718 {
1719 if (context->getClientVersion() < ES_3_1)
1720 {
1721 context->validationError(GL_INVALID_OPERATION, kES31Required);
1722 return false;
1723 }
1724
1725 return true;
1726 }
1727
ValidateUseProgramStages(const Context * context,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1728 bool ValidateUseProgramStages(const Context *context,
1729 ProgramPipelineID pipeline,
1730 GLbitfield stages,
1731 ShaderProgramID programId)
1732 {
1733 if (context->getClientVersion() < ES_3_1)
1734 {
1735 context->validationError(GL_INVALID_OPERATION, kES31Required);
1736 return false;
1737 }
1738
1739 // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
1740 // not the reserved value GL_ALL_SHADER_BITS.
1741 const GLbitfield knownShaderBits =
1742 GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1743 if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1744 {
1745 context->validationError(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1746 return false;
1747 }
1748
1749 // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1750 // to glGenProgramPipelines or if such a name has been deleted by a call to
1751 // glDeleteProgramPipelines.
1752 if (!context->isProgramPipelineGenerated({pipeline}))
1753 {
1754 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1755 return false;
1756 }
1757
1758 // If program is zero, or refers to a program object with no valid shader executable for a given
1759 // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1760 // shader stages.
1761 if (programId.value == 0)
1762 {
1763 return true;
1764 }
1765
1766 Program *program = context->getProgramNoResolveLink(programId);
1767 if (!program)
1768 {
1769 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1770 return false;
1771 }
1772
1773 // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1774 // with its GL_PROGRAM_SEPARABLE status set.
1775 // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1776 // glDetachShader() was not called.
1777 program->resolveLink(context);
1778 if (!program->isSeparable())
1779 {
1780 context->validationError(GL_INVALID_OPERATION, kProgramNotSeparable);
1781 return false;
1782 }
1783
1784 // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1785 // successfully linked.
1786 if (!program->isLinked())
1787 {
1788 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1789 return false;
1790 }
1791
1792 return true;
1793 }
1794
ValidateActiveShaderProgram(const Context * context,ProgramPipelineID pipeline,ShaderProgramID programId)1795 bool ValidateActiveShaderProgram(const Context *context,
1796 ProgramPipelineID pipeline,
1797 ShaderProgramID programId)
1798 {
1799 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1800 // call to GenProgramPipelines or if such a name has since been deleted by
1801 // DeleteProgramPipelines.
1802 if (!context->isProgramPipelineGenerated({pipeline}))
1803 {
1804 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1805 return false;
1806 }
1807
1808 // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1809 // program or shader object.
1810 if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1811 {
1812 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1813 return false;
1814 }
1815
1816 // An INVALID_OPERATION error is generated if program is the name of a shader object.
1817 if (context->isShader(programId))
1818 {
1819 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
1820 return false;
1821 }
1822
1823 // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1824 // was last linked unsuccessfully. The active program is not modified.
1825 Program *program = context->getProgramNoResolveLink(programId);
1826 if ((programId.value != 0) && !program->isLinked())
1827 {
1828 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1829 return false;
1830 }
1831
1832 return true;
1833 }
1834
ValidateCreateShaderProgramv(const Context * context,ShaderType type,GLsizei count,const GLchar * const * strings)1835 bool ValidateCreateShaderProgramv(const Context *context,
1836 ShaderType type,
1837 GLsizei count,
1838 const GLchar *const *strings)
1839 {
1840 if (context->getClientVersion() < ES_3_1)
1841 {
1842 context->validationError(GL_INVALID_OPERATION, kES31Required);
1843 return false;
1844 }
1845
1846 // GL_INVALID_ENUM is generated if type is not an accepted shader type.
1847 if ((type != ShaderType::Vertex) && (type != ShaderType::Fragment) &&
1848 (type != ShaderType::Compute))
1849 {
1850 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1851 return false;
1852 }
1853
1854 // GL_INVALID_VALUE is generated if count is negative.
1855 if (count < 0)
1856 {
1857 context->validationError(GL_INVALID_VALUE, kNegativeCount);
1858 return false;
1859 }
1860
1861 return true;
1862 }
1863
ValidateGetProgramPipelineiv(const Context * context,ProgramPipelineID pipeline,GLenum pname,const GLint * params)1864 bool ValidateGetProgramPipelineiv(const Context *context,
1865 ProgramPipelineID pipeline,
1866 GLenum pname,
1867 const GLint *params)
1868 {
1869 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1870 // call to GenProgramPipelines or if such a name has since been deleted by
1871 // DeleteProgramPipelines.
1872 if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
1873 {
1874 context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1875 return false;
1876 }
1877
1878 // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
1879 // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
1880 // table 7.1.
1881 switch (pname)
1882 {
1883 case GL_ACTIVE_PROGRAM:
1884 case GL_INFO_LOG_LENGTH:
1885 case GL_VALIDATE_STATUS:
1886 case GL_VERTEX_SHADER:
1887 case GL_FRAGMENT_SHADER:
1888 case GL_COMPUTE_SHADER:
1889 break;
1890
1891 default:
1892 context->validationError(GL_INVALID_ENUM, kInvalidPname);
1893 return false;
1894 }
1895
1896 return true;
1897 }
1898
ValidateValidateProgramPipeline(const Context * context,ProgramPipelineID pipeline)1899 bool ValidateValidateProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1900 {
1901 if (pipeline.value == 0)
1902 {
1903 return false;
1904 }
1905
1906 if (!context->isProgramPipelineGenerated(pipeline))
1907 {
1908 context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1909 return false;
1910 }
1911
1912 return true;
1913 }
1914
ValidateGetProgramPipelineInfoLog(const Context * context,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)1915 bool ValidateGetProgramPipelineInfoLog(const Context *context,
1916 ProgramPipelineID pipeline,
1917 GLsizei bufSize,
1918 const GLsizei *length,
1919 const GLchar *infoLog)
1920 {
1921 if (bufSize < 0)
1922 {
1923 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1924 return false;
1925 }
1926
1927 if (!context->isProgramPipelineGenerated(pipeline))
1928 {
1929 context->validationError(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
1930 return false;
1931 }
1932
1933 return true;
1934 }
1935
ValidateMemoryBarrier(const Context * context,GLbitfield barriers)1936 bool ValidateMemoryBarrier(const Context *context, GLbitfield barriers)
1937 {
1938 if (context->getClientVersion() < ES_3_1)
1939 {
1940 context->validationError(GL_INVALID_OPERATION, kES31Required);
1941 return false;
1942 }
1943
1944 if (barriers == GL_ALL_BARRIER_BITS)
1945 {
1946 return true;
1947 }
1948
1949 GLbitfield supported_barrier_bits =
1950 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1951 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1952 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1953 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1954 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1955 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
1956 {
1957 context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
1958 return false;
1959 }
1960
1961 return true;
1962 }
1963
ValidateMemoryBarrierByRegion(const Context * context,GLbitfield barriers)1964 bool ValidateMemoryBarrierByRegion(const Context *context, GLbitfield barriers)
1965 {
1966 if (context->getClientVersion() < ES_3_1)
1967 {
1968 context->validationError(GL_INVALID_OPERATION, kES31Required);
1969 return false;
1970 }
1971
1972 if (barriers == GL_ALL_BARRIER_BITS)
1973 {
1974 return true;
1975 }
1976
1977 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1978 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1979 GL_SHADER_STORAGE_BARRIER_BIT |
1980 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1981 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
1982 {
1983 context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
1984 return false;
1985 }
1986
1987 return true;
1988 }
1989
ValidateSampleMaski(const Context * context,GLuint maskNumber,GLbitfield mask)1990 bool ValidateSampleMaski(const Context *context, GLuint maskNumber, GLbitfield mask)
1991 {
1992 if (context->getClientVersion() < ES_3_1)
1993 {
1994 context->validationError(GL_INVALID_OPERATION, kES31Required);
1995 return false;
1996 }
1997
1998 return ValidateSampleMaskiBase(context, maskNumber, mask);
1999 }
2000
ValidateFramebufferTextureEXT(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2001 bool ValidateFramebufferTextureEXT(const Context *context,
2002 GLenum target,
2003 GLenum attachment,
2004 TextureID texture,
2005 GLint level)
2006 {
2007 if (!context->getExtensions().geometryShader)
2008 {
2009 context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2010 return false;
2011 }
2012
2013 if (texture.value != 0)
2014 {
2015 Texture *tex = context->getTexture(texture);
2016
2017 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2018 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2019 // We put this validation before ValidateFramebufferTextureBase because it is an
2020 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2021 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2022 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2023 // existing texture object of type matching textarget.
2024 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2025 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2026 // three-dimensional or two-dimensional array texture.
2027 if (tex == nullptr)
2028 {
2029 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
2030 return false;
2031 }
2032
2033 if (!ValidMipLevel(context, tex->getType(), level))
2034 {
2035 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
2036 return false;
2037 }
2038 }
2039
2040 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
2041 {
2042 return false;
2043 }
2044
2045 return true;
2046 }
2047
2048 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,TextureType target,GLsizei samples,GLenum sizedinternalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)2049 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2050 TextureType target,
2051 GLsizei samples,
2052 GLenum sizedinternalformat,
2053 GLsizei width,
2054 GLsizei height,
2055 GLsizei depth,
2056 GLboolean fixedsamplelocations)
2057 {
2058 if (!context->getExtensions().textureStorageMultisample2DArrayOES)
2059 {
2060 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
2061 return false;
2062 }
2063
2064 if (target != TextureType::_2DMultisampleArray)
2065 {
2066 context->validationError(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
2067 return false;
2068 }
2069
2070 if (width < 1 || height < 1 || depth < 1)
2071 {
2072 context->validationError(GL_INVALID_VALUE, kNegativeSize);
2073 return false;
2074 }
2075
2076 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
2077 height);
2078 }
2079
ValidateTexStorageMem3DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)2080 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
2081 TextureType target,
2082 GLsizei samples,
2083 GLenum internalFormat,
2084 GLsizei width,
2085 GLsizei height,
2086 GLsizei depth,
2087 GLboolean fixedSampleLocations,
2088 MemoryObjectID memory,
2089 GLuint64 offset)
2090 {
2091 if (!context->getExtensions().memoryObject)
2092 {
2093 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2094 return false;
2095 }
2096
2097 UNIMPLEMENTED();
2098 return false;
2099 }
2100
ValidateGetProgramResourceLocationIndexEXT(const Context * context,ShaderProgramID program,GLenum programInterface,const char * name)2101 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
2102 ShaderProgramID program,
2103 GLenum programInterface,
2104 const char *name)
2105 {
2106 if (!context->getExtensions().blendFuncExtended)
2107 {
2108 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2109 return false;
2110 }
2111 if (context->getClientVersion() < ES_3_1)
2112 {
2113 context->validationError(GL_INVALID_OPERATION, kES31Required);
2114 return false;
2115 }
2116 if (programInterface != GL_PROGRAM_OUTPUT)
2117 {
2118 context->validationError(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
2119 return false;
2120 }
2121 Program *programObject = GetValidProgram(context, program);
2122 if (!programObject)
2123 {
2124 return false;
2125 }
2126 if (!programObject->isLinked())
2127 {
2128 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
2129 return false;
2130 }
2131 return true;
2132 }
2133
2134 } // namespace gl
2135