blob: 26b0b16ca1e6c91d29bf56e11abd33fa436cfd7f [file] [log] [blame]
Martin Radev66fb8202016-07-28 11:45:20 +03001//
2// Copyright (c) 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
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES31_autogen.h"
Martin Radev66fb8202016-07-28 11:45:20 +030010
11#include "libANGLE/Context.h"
Brandon Jonesafa75152017-07-21 13:11:29 -070012#include "libANGLE/ErrorStrings.h"
JiangYizhouf7bbc8a2016-11-16 09:57:22 +080013#include "libANGLE/Framebuffer.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040014#include "libANGLE/VertexArray.h"
Geoff Lang2e43dbb2016-10-14 12:27:35 -040015#include "libANGLE/validationES.h"
Jamie Madill778bf092018-11-14 09:54:36 -050016#include "libANGLE/validationES2_autogen.h"
17#include "libANGLE/validationES3_autogen.h"
Martin Radev66fb8202016-07-28 11:45:20 +030018
He Yunchao11b038b2016-11-22 21:24:04 +080019#include "common/utilities.h"
20
Martin Radev66fb8202016-07-28 11:45:20 +030021using namespace angle;
22
23namespace gl
24{
25
jchen1015015f72017-03-16 13:54:21 +080026namespace
27{
28
29bool ValidateNamedProgramInterface(GLenum programInterface)
30{
31 switch (programInterface)
32 {
33 case GL_UNIFORM:
34 case GL_UNIFORM_BLOCK:
35 case GL_PROGRAM_INPUT:
36 case GL_PROGRAM_OUTPUT:
37 case GL_TRANSFORM_FEEDBACK_VARYING:
38 case GL_BUFFER_VARIABLE:
39 case GL_SHADER_STORAGE_BLOCK:
40 return true;
41 default:
42 return false;
43 }
44}
45
jchen10191381f2017-04-11 13:59:04 +080046bool ValidateLocationProgramInterface(GLenum programInterface)
47{
48 switch (programInterface)
49 {
50 case GL_UNIFORM:
51 case GL_PROGRAM_INPUT:
52 case GL_PROGRAM_OUTPUT:
53 return true;
54 default:
55 return false;
56 }
57}
58
jchen10880683b2017-04-12 16:21:55 +080059bool ValidateProgramInterface(GLenum programInterface)
60{
61 return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
62 ValidateNamedProgramInterface(programInterface));
63}
64
Jiawei Shaoc6f82872018-04-24 14:14:50 +080065bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
jchen10880683b2017-04-12 16:21:55 +080066{
Jiawei Shaoc6f82872018-04-24 14:14:50 +080067 ASSERT(context);
jchen10880683b2017-04-12 16:21:55 +080068 switch (prop)
69 {
70 case GL_ACTIVE_VARIABLES:
71 case GL_BUFFER_BINDING:
72 case GL_NUM_ACTIVE_VARIABLES:
73
74 case GL_ARRAY_SIZE:
75
76 case GL_ARRAY_STRIDE:
77 case GL_BLOCK_INDEX:
78 case GL_IS_ROW_MAJOR:
79 case GL_MATRIX_STRIDE:
80
81 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
82
83 case GL_BUFFER_DATA_SIZE:
84
85 case GL_LOCATION:
86
87 case GL_NAME_LENGTH:
88
89 case GL_OFFSET:
90
91 case GL_REFERENCED_BY_VERTEX_SHADER:
92 case GL_REFERENCED_BY_FRAGMENT_SHADER:
93 case GL_REFERENCED_BY_COMPUTE_SHADER:
94
95 case GL_TOP_LEVEL_ARRAY_SIZE:
96 case GL_TOP_LEVEL_ARRAY_STRIDE:
97
98 case GL_TYPE:
99 return true;
100
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800101 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
102 return context->getExtensions().geometryShader;
103
Olli Etuaho0ca09752018-09-24 11:00:50 +0300104 case GL_LOCATION_INDEX_EXT:
105 return context->getExtensions().blendFuncExtended;
106
jchen10880683b2017-04-12 16:21:55 +0800107 default:
108 return false;
109 }
110}
111
112// GLES 3.10 spec: Page 82 -- Table 7.2
113bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
114{
115 switch (prop)
116 {
117 case GL_ACTIVE_VARIABLES:
118 case GL_BUFFER_BINDING:
119 case GL_NUM_ACTIVE_VARIABLES:
120 {
121 switch (programInterface)
122 {
123 case GL_ATOMIC_COUNTER_BUFFER:
124 case GL_SHADER_STORAGE_BLOCK:
125 case GL_UNIFORM_BLOCK:
126 return true;
127 default:
128 return false;
129 }
130 }
131
132 case GL_ARRAY_SIZE:
133 {
134 switch (programInterface)
135 {
136 case GL_BUFFER_VARIABLE:
137 case GL_PROGRAM_INPUT:
138 case GL_PROGRAM_OUTPUT:
139 case GL_TRANSFORM_FEEDBACK_VARYING:
140 case GL_UNIFORM:
141 return true;
142 default:
143 return false;
144 }
145 }
146
147 case GL_ARRAY_STRIDE:
148 case GL_BLOCK_INDEX:
149 case GL_IS_ROW_MAJOR:
150 case GL_MATRIX_STRIDE:
151 {
152 switch (programInterface)
153 {
154 case GL_BUFFER_VARIABLE:
155 case GL_UNIFORM:
156 return true;
157 default:
158 return false;
159 }
160 }
161
162 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
163 {
164 if (programInterface == GL_UNIFORM)
165 {
166 return true;
167 }
168 return false;
169 }
170
171 case GL_BUFFER_DATA_SIZE:
172 {
173 switch (programInterface)
174 {
175 case GL_ATOMIC_COUNTER_BUFFER:
176 case GL_SHADER_STORAGE_BLOCK:
177 case GL_UNIFORM_BLOCK:
178 return true;
179 default:
180 return false;
181 }
182 }
183
184 case GL_LOCATION:
185 {
186 return ValidateLocationProgramInterface(programInterface);
187 }
188
Olli Etuaho0ca09752018-09-24 11:00:50 +0300189 case GL_LOCATION_INDEX_EXT:
190 {
191 // EXT_blend_func_extended
192 return (programInterface == GL_PROGRAM_OUTPUT);
193 }
194
jchen10880683b2017-04-12 16:21:55 +0800195 case GL_NAME_LENGTH:
196 {
197 return ValidateNamedProgramInterface(programInterface);
198 }
199
200 case GL_OFFSET:
201 {
202 switch (programInterface)
203 {
204 case GL_BUFFER_VARIABLE:
205 case GL_UNIFORM:
206 return true;
207 default:
208 return false;
209 }
210 }
211
212 case GL_REFERENCED_BY_VERTEX_SHADER:
213 case GL_REFERENCED_BY_FRAGMENT_SHADER:
214 case GL_REFERENCED_BY_COMPUTE_SHADER:
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800215 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
jchen10880683b2017-04-12 16:21:55 +0800216 {
217 switch (programInterface)
218 {
219 case GL_ATOMIC_COUNTER_BUFFER:
220 case GL_BUFFER_VARIABLE:
221 case GL_PROGRAM_INPUT:
222 case GL_PROGRAM_OUTPUT:
223 case GL_SHADER_STORAGE_BLOCK:
224 case GL_UNIFORM:
225 case GL_UNIFORM_BLOCK:
226 return true;
227 default:
228 return false;
229 }
230 }
231
232 case GL_TOP_LEVEL_ARRAY_SIZE:
233 case GL_TOP_LEVEL_ARRAY_STRIDE:
234 {
235 if (programInterface == GL_BUFFER_VARIABLE)
236 {
237 return true;
238 }
239 return false;
240 }
241
242 case GL_TYPE:
243 {
244 switch (programInterface)
245 {
246 case GL_BUFFER_VARIABLE:
247 case GL_PROGRAM_INPUT:
248 case GL_PROGRAM_OUTPUT:
249 case GL_TRANSFORM_FEEDBACK_VARYING:
250 case GL_UNIFORM:
251 return true;
252 default:
253 return false;
254 }
255 }
256
257 default:
258 return false;
259 }
260}
261
jchen10fd7c3b52017-03-21 15:36:03 +0800262bool ValidateProgramResourceIndex(const Program *programObject,
263 GLenum programInterface,
264 GLuint index)
265{
266 switch (programInterface)
267 {
268 case GL_PROGRAM_INPUT:
269 return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
270
271 case GL_PROGRAM_OUTPUT:
272 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
273
jchen10fd7c3b52017-03-21 15:36:03 +0800274 case GL_UNIFORM:
jchen10baf5d942017-08-28 20:45:48 +0800275 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
276
Jiajia Qin3a9090f2017-09-27 14:37:04 +0800277 case GL_BUFFER_VARIABLE:
278 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
279
280 case GL_SHADER_STORAGE_BLOCK:
281 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
282
jchen10fd7c3b52017-03-21 15:36:03 +0800283 case GL_UNIFORM_BLOCK:
jchen1058f67be2017-10-27 08:59:27 +0800284 return (index < programObject->getActiveUniformBlockCount());
285
286 case GL_ATOMIC_COUNTER_BUFFER:
287 return (index < programObject->getActiveAtomicCounterBufferCount());
288
jchen10fd7c3b52017-03-21 15:36:03 +0800289 case GL_TRANSFORM_FEEDBACK_VARYING:
jchen10910a3da2017-11-15 09:40:11 +0800290 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
jchen10fd7c3b52017-03-21 15:36:03 +0800291
292 default:
293 UNREACHABLE();
294 return false;
295 }
296}
297
Jamie Madill5b772312018-03-08 20:28:32 -0500298bool ValidateProgramUniform(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800299 GLenum valueType,
300 GLuint program,
301 GLint location,
302 GLsizei count)
303{
304 // Check for ES31 program uniform entry points
305 if (context->getClientVersion() < Version(3, 1))
306 {
307 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
308 return false;
309 }
310
311 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500312 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800313 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
314 ValidateUniformValue(context, valueType, uniform->type);
315}
316
Jamie Madill5b772312018-03-08 20:28:32 -0500317bool ValidateProgramUniformMatrix(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800318 GLenum valueType,
319 GLuint program,
320 GLint location,
321 GLsizei count,
322 GLboolean transpose)
323{
324 // Check for ES31 program uniform entry points
325 if (context->getClientVersion() < Version(3, 1))
326 {
327 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
328 return false;
329 }
330
331 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500332 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800333 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
334 ValidateUniformMatrixValue(context, valueType, uniform->type);
335}
336
Jamie Madill5b772312018-03-08 20:28:32 -0500337bool ValidateVertexAttribFormatCommon(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800338 GLuint attribIndex,
339 GLint size,
340 GLenum type,
341 GLuint relativeOffset,
342 GLboolean pureInteger)
343{
344 if (context->getClientVersion() < ES_3_1)
345 {
346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
347 return false;
348 }
349
350 const Caps &caps = context->getCaps();
351 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
352 {
353 context->handleError(
354 InvalidValue()
355 << "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
356 return false;
357 }
358
359 // [OpenGL ES 3.1] Section 10.3.1 page 243:
360 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
361 if (context->getGLState().getVertexArrayId() == 0)
362 {
363 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
364 return false;
365 }
366
367 return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
368}
369
jchen1015015f72017-03-16 13:54:21 +0800370} // anonymous namespace
371
Martin Radev66fb8202016-07-28 11:45:20 +0300372bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
373{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400374 if (context->getClientVersion() < ES_3_1)
Martin Radev66fb8202016-07-28 11:45:20 +0300375 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Martin Radev66fb8202016-07-28 11:45:20 +0300377 return false;
378 }
379
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400380 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
381 {
382 return false;
383 }
384
385 return true;
386}
387
388bool ValidateGetBooleani_vRobustANGLE(Context *context,
389 GLenum target,
390 GLuint index,
391 GLsizei bufSize,
392 GLsizei *length,
393 GLboolean *data)
394{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400395 if (context->getClientVersion() < ES_3_1)
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400396 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700397 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400398 return false;
399 }
400
401 if (!ValidateRobustEntryPoint(context, bufSize))
402 {
403 return false;
404 }
405
Brandon Jonesd1049182018-03-28 10:02:20 -0700406 GLsizei numParams = 0;
407
408 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400409 {
410 return false;
411 }
412
Brandon Jonesd1049182018-03-28 10:02:20 -0700413 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Martin Radev66fb8202016-07-28 11:45:20 +0300414 {
415 return false;
416 }
417
Brandon Jonesd1049182018-03-28 10:02:20 -0700418 SetRobustLengthParam(length, numParams);
Martin Radev66fb8202016-07-28 11:45:20 +0300419 return true;
420}
421
Jamie Madill493f9572018-05-24 19:52:15 -0400422bool ValidateDrawIndirectBase(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800423{
424 if (context->getClientVersion() < ES_3_1)
425 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700426 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jiajia Qind9671222016-11-29 16:30:31 +0800427 return false;
428 }
429
430 // Here the third parameter 1 is only to pass the count validation.
431 if (!ValidateDrawBase(context, mode, 1))
432 {
433 return false;
434 }
435
436 const State &state = context->getGLState();
437
438 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
439 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
440 if (!state.getVertexArrayId())
441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500442 context->handleError(InvalidOperation() << "zero is bound to VERTEX_ARRAY_BINDING");
Jiajia Qind9671222016-11-29 16:30:31 +0800443 return false;
444 }
445
Jamie Madill5b772312018-03-08 20:28:32 -0500446 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800447 if (!drawIndirectBuffer)
448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500449 context->handleError(InvalidOperation() << "zero is bound to DRAW_INDIRECT_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800450 return false;
451 }
452
453 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
454 // machine units, of uint.
455 GLint64 offset = reinterpret_cast<GLint64>(indirect);
456 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
457 {
458 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500459 InvalidValue()
460 << "indirect is not a multiple of the size, in basic machine units, of uint");
Jiajia Qind9671222016-11-29 16:30:31 +0800461 return false;
462 }
463
Martin Radev14a26ae2017-07-24 15:56:29 +0300464 // ANGLE_multiview spec, revision 1:
465 // An INVALID_OPERATION is generated by DrawArraysIndirect and DrawElementsIndirect if the
466 // number of views in the draw framebuffer is greater than 1.
467 const Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
468 ASSERT(drawFramebuffer != nullptr);
469 if (drawFramebuffer->getNumViews() > 1)
470 {
471 context->handleError(
472 InvalidOperation()
473 << "The number of views in the active draw framebuffer is greater than 1.");
474 return false;
475 }
476
Jiajia Qind9671222016-11-29 16:30:31 +0800477 return true;
478}
479
Jamie Madill493f9572018-05-24 19:52:15 -0400480bool ValidateDrawArraysIndirect(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800481{
Jamie Madill493f9572018-05-24 19:52:15 -0400482 const State &state = context->getGLState();
483 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
Jiajia Qind9671222016-11-29 16:30:31 +0800484 if (curTransformFeedback && curTransformFeedback->isActive() &&
485 !curTransformFeedback->isPaused())
486 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800487 // EXT_geometry_shader allows transform feedback to work with all draw commands.
488 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
489 if (context->getExtensions().geometryShader)
490 {
491 if (!ValidateTransformFeedbackPrimitiveMode(
492 context, curTransformFeedback->getPrimitiveMode(), mode))
493 {
494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
495 return false;
496 }
497 }
498 else
499 {
500 // An INVALID_OPERATION error is generated if transform feedback is active and not
501 // paused.
502 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
503 UnsupportedDrawModeForTransformFeedback);
504 return false;
505 }
Jiajia Qind9671222016-11-29 16:30:31 +0800506 }
507
508 if (!ValidateDrawIndirectBase(context, mode, indirect))
509 return false;
510
Jamie Madill5b772312018-03-08 20:28:32 -0500511 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800512 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
513 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
514 // which's size is 4 * sizeof(uint).
515 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
516 if (!checkedSum.IsValid() ||
517 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
518 {
519 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500520 InvalidOperation()
521 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800522 return false;
523 }
524
525 return true;
526}
527
Jamie Madill493f9572018-05-24 19:52:15 -0400528bool ValidateDrawElementsIndirect(Context *context,
529 PrimitiveMode mode,
530 GLenum type,
531 const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800532{
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800533 if (!ValidateDrawElementsBase(context, mode, type))
534 {
Jiajia Qind9671222016-11-29 16:30:31 +0800535 return false;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800536 }
Jiajia Qind9671222016-11-29 16:30:31 +0800537
Jamie Madill493f9572018-05-24 19:52:15 -0400538 const State &state = context->getGLState();
539 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400540 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jiajia Qind9671222016-11-29 16:30:31 +0800541 if (!elementArrayBuffer)
542 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500543 context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800544 return false;
545 }
546
547 if (!ValidateDrawIndirectBase(context, mode, indirect))
548 return false;
549
Jamie Madill5b772312018-03-08 20:28:32 -0500550 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800551 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
552 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
553 // which's size is 5 * sizeof(uint).
554 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
555 if (!checkedSum.IsValid() ||
556 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
557 {
558 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500559 InvalidOperation()
560 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800561 return false;
562 }
563
564 return true;
565}
566
Jiajia Qin5451d532017-11-16 17:16:34 +0800567bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0)
568{
569 return ValidateProgramUniform1iv(context, program, location, 1, &v0);
570}
571
572bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1)
573{
574 GLint xy[2] = {v0, v1};
575 return ValidateProgramUniform2iv(context, program, location, 1, xy);
576}
577
578bool ValidateProgramUniform3i(Context *context,
579 GLuint program,
580 GLint location,
581 GLint v0,
582 GLint v1,
583 GLint v2)
584{
585 GLint xyz[3] = {v0, v1, v2};
586 return ValidateProgramUniform3iv(context, program, location, 1, xyz);
587}
588
589bool ValidateProgramUniform4i(Context *context,
590 GLuint program,
591 GLint location,
592 GLint v0,
593 GLint v1,
594 GLint v2,
595 GLint v3)
596{
597 GLint xyzw[4] = {v0, v1, v2, v3};
598 return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
599}
600
601bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0)
602{
603 return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
604}
605
606bool ValidateProgramUniform2ui(Context *context,
607 GLuint program,
608 GLint location,
609 GLuint v0,
610 GLuint v1)
611{
612 GLuint xy[2] = {v0, v1};
613 return ValidateProgramUniform2uiv(context, program, location, 1, xy);
614}
615
616bool ValidateProgramUniform3ui(Context *context,
617 GLuint program,
618 GLint location,
619 GLuint v0,
620 GLuint v1,
621 GLuint v2)
622{
623 GLuint xyz[3] = {v0, v1, v2};
624 return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
625}
626
627bool ValidateProgramUniform4ui(Context *context,
628 GLuint program,
629 GLint location,
630 GLuint v0,
631 GLuint v1,
632 GLuint v2,
633 GLuint v3)
634{
635 GLuint xyzw[4] = {v0, v1, v2, v3};
636 return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
637}
638
639bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0)
640{
641 return ValidateProgramUniform1fv(context, program, location, 1, &v0);
642}
643
644bool ValidateProgramUniform2f(Context *context,
645 GLuint program,
646 GLint location,
647 GLfloat v0,
648 GLfloat v1)
649{
650 GLfloat xy[2] = {v0, v1};
651 return ValidateProgramUniform2fv(context, program, location, 1, xy);
652}
653
654bool ValidateProgramUniform3f(Context *context,
655 GLuint program,
656 GLint location,
657 GLfloat v0,
658 GLfloat v1,
659 GLfloat v2)
660{
661 GLfloat xyz[3] = {v0, v1, v2};
662 return ValidateProgramUniform3fv(context, program, location, 1, xyz);
663}
664
665bool ValidateProgramUniform4f(Context *context,
666 GLuint program,
667 GLint location,
668 GLfloat v0,
669 GLfloat v1,
670 GLfloat v2,
671 GLfloat v3)
672{
673 GLfloat xyzw[4] = {v0, v1, v2, v3};
674 return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
675}
676
677bool ValidateProgramUniform1iv(Context *context,
678 GLuint program,
679 GLint location,
680 GLsizei count,
681 const GLint *value)
682{
683 // Check for ES31 program uniform entry points
684 if (context->getClientVersion() < Version(3, 1))
685 {
686 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
687 return false;
688 }
689
690 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500691 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800692 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
693 ValidateUniform1ivValue(context, uniform->type, count, value);
694}
695
696bool ValidateProgramUniform2iv(Context *context,
697 GLuint program,
698 GLint location,
699 GLsizei count,
700 const GLint *value)
701{
702 return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
703}
704
705bool ValidateProgramUniform3iv(Context *context,
706 GLuint program,
707 GLint location,
708 GLsizei count,
709 const GLint *value)
710{
711 return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
712}
713
714bool ValidateProgramUniform4iv(Context *context,
715 GLuint program,
716 GLint location,
717 GLsizei count,
718 const GLint *value)
719{
720 return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
721}
722
723bool ValidateProgramUniform1uiv(Context *context,
724 GLuint program,
725 GLint location,
726 GLsizei count,
727 const GLuint *value)
728{
729 return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
730}
731
732bool ValidateProgramUniform2uiv(Context *context,
733 GLuint program,
734 GLint location,
735 GLsizei count,
736 const GLuint *value)
737{
738 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
739}
740
741bool ValidateProgramUniform3uiv(Context *context,
742 GLuint program,
743 GLint location,
744 GLsizei count,
745 const GLuint *value)
746{
747 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
748}
749
750bool ValidateProgramUniform4uiv(Context *context,
751 GLuint program,
752 GLint location,
753 GLsizei count,
754 const GLuint *value)
755{
756 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
757}
758
759bool ValidateProgramUniform1fv(Context *context,
760 GLuint program,
761 GLint location,
762 GLsizei count,
763 const GLfloat *value)
764{
765 return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
766}
767
768bool ValidateProgramUniform2fv(Context *context,
769 GLuint program,
770 GLint location,
771 GLsizei count,
772 const GLfloat *value)
773{
774 return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
775}
776
777bool ValidateProgramUniform3fv(Context *context,
778 GLuint program,
779 GLint location,
780 GLsizei count,
781 const GLfloat *value)
782{
783 return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
784}
785
786bool ValidateProgramUniform4fv(Context *context,
787 GLuint program,
788 GLint location,
789 GLsizei count,
790 const GLfloat *value)
791{
792 return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
793}
794
795bool ValidateProgramUniformMatrix2fv(Context *context,
796 GLuint program,
797 GLint location,
798 GLsizei count,
799 GLboolean transpose,
800 const GLfloat *value)
801{
802 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
803 transpose);
804}
805
806bool ValidateProgramUniformMatrix3fv(Context *context,
807 GLuint program,
808 GLint location,
809 GLsizei count,
810 GLboolean transpose,
811 const GLfloat *value)
812{
813 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
814 transpose);
815}
816
817bool ValidateProgramUniformMatrix4fv(Context *context,
818 GLuint program,
819 GLint location,
820 GLsizei count,
821 GLboolean transpose,
822 const GLfloat *value)
823{
824 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
825 transpose);
826}
827
828bool ValidateProgramUniformMatrix2x3fv(Context *context,
829 GLuint program,
830 GLint location,
831 GLsizei count,
832 GLboolean transpose,
833 const GLfloat *value)
834{
835 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
836 transpose);
837}
838
839bool ValidateProgramUniformMatrix3x2fv(Context *context,
840 GLuint program,
841 GLint location,
842 GLsizei count,
843 GLboolean transpose,
844 const GLfloat *value)
845{
846 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
847 transpose);
848}
849
850bool ValidateProgramUniformMatrix2x4fv(Context *context,
851 GLuint program,
852 GLint location,
853 GLsizei count,
854 GLboolean transpose,
855 const GLfloat *value)
856{
857 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
858 transpose);
859}
860
861bool ValidateProgramUniformMatrix4x2fv(Context *context,
862 GLuint program,
863 GLint location,
864 GLsizei count,
865 GLboolean transpose,
866 const GLfloat *value)
867{
868 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
869 transpose);
870}
871
872bool ValidateProgramUniformMatrix3x4fv(Context *context,
873 GLuint program,
874 GLint location,
875 GLsizei count,
876 GLboolean transpose,
877 const GLfloat *value)
878{
879 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
880 transpose);
881}
882
883bool ValidateProgramUniformMatrix4x3fv(Context *context,
884 GLuint program,
885 GLint location,
886 GLsizei count,
887 GLboolean transpose,
888 const GLfloat *value)
889{
890 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
891 transpose);
892}
893
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800894bool ValidateGetTexLevelParameterfv(Context *context,
895 TextureTarget target,
896 GLint level,
897 GLenum pname,
898 GLfloat *params)
He Yunchao11b038b2016-11-22 21:24:04 +0800899{
900 if (context->getClientVersion() < ES_3_1)
901 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700902 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
He Yunchao11b038b2016-11-22 21:24:04 +0800903 return false;
904 }
905
He Yunchao11b038b2016-11-22 21:24:04 +0800906 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
907}
908
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700909bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
910 TextureTarget target,
911 GLint level,
912 GLenum pname,
913 GLsizei bufSize,
914 GLsizei *length,
915 GLfloat *params)
916{
917 UNIMPLEMENTED();
918 return false;
919}
920
He Yunchao11b038b2016-11-22 21:24:04 +0800921bool ValidateGetTexLevelParameteriv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800922 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800923 GLint level,
924 GLenum pname,
925 GLint *params)
926{
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800927 if (context->getClientVersion() < ES_3_1)
928 {
929 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
930 return false;
931 }
932
He Yunchao11b038b2016-11-22 21:24:04 +0800933 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
934}
935
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700936bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
937 TextureTarget target,
938 GLint level,
939 GLenum pname,
940 GLsizei bufSize,
941 GLsizei *length,
942 GLint *params)
943{
944 UNIMPLEMENTED();
945 return false;
946}
947
Jiajia Qin5451d532017-11-16 17:16:34 +0800948bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800949 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800950 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -0500951 GLenum internalFormat,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800952 GLsizei width,
953 GLsizei height,
954 GLboolean fixedSampleLocations)
955{
956 if (context->getClientVersion() < ES_3_1)
957 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700958 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800959 return false;
960 }
961
Yizhou Jiang7818a852018-09-06 15:02:04 +0800962 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
963 height);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800964}
965
966bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
967{
968 if (context->getClientVersion() < ES_3_1)
969 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700970 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800971 return false;
972 }
973
974 if (pname != GL_SAMPLE_POSITION)
975 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500976 context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
JiangYizhoubddc46b2016-12-09 09:50:51 +0800977 return false;
978 }
979
JiangYizhou5b03f472017-01-09 10:22:53 +0800980 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -0400981 GLint samples = framebuffer->getSamples(context);
JiangYizhou5b03f472017-01-09 10:22:53 +0800982
Jamie Madille98b1b52018-03-08 09:47:23 -0500983 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +0800984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500985 context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
JiangYizhoubddc46b2016-12-09 09:50:51 +0800986 return false;
987 }
988
989 return true;
990}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800991
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700992bool ValidateGetMultisamplefvRobustANGLE(Context *context,
993 GLenum pname,
994 GLuint index,
995 GLsizei bufSize,
996 GLsizei *length,
997 GLfloat *val)
998{
999 UNIMPLEMENTED();
1000 return false;
1001}
1002
Jiajia Qin5451d532017-11-16 17:16:34 +08001003bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001004{
1005 if (context->getClientVersion() < ES_3_1)
1006 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001007 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001008 return false;
1009 }
1010
Geoff Lange8afa902017-09-27 15:00:43 -04001011 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001012 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001013 context->handleError(InvalidEnum() << "Invalid framebuffer target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001014 return false;
1015 }
1016
1017 switch (pname)
1018 {
1019 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1020 {
1021 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1022 if (param < 0 || param > maxWidth)
1023 {
1024 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001025 InvalidValue()
1026 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001027 return false;
1028 }
1029 break;
1030 }
1031 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1032 {
1033 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1034 if (param < 0 || param > maxHeight)
1035 {
1036 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001037 InvalidValue()
1038 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001039 return false;
1040 }
1041 break;
1042 }
1043 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1044 {
1045 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1046 if (param < 0 || param > maxSamples)
1047 {
1048 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001049 InvalidValue()
1050 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001051 return false;
1052 }
1053 break;
1054 }
1055 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1056 {
1057 break;
1058 }
Jiawei Shaob1e91382018-05-17 14:33:55 +08001059 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1060 {
1061 if (!context->getExtensions().geometryShader)
1062 {
1063 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1064 return false;
1065 }
1066 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1067 if (param < 0 || param > maxLayers)
1068 {
1069 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferLayer);
1070 return false;
1071 }
1072 break;
1073 }
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001074 default:
1075 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001076 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001077 return false;
1078 }
1079 }
1080
1081 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1082 ASSERT(framebuffer);
1083 if (framebuffer->id() == 0)
1084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001085 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001086 return false;
1087 }
1088 return true;
1089}
1090
Jiajia Qin5451d532017-11-16 17:16:34 +08001091bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001092{
1093 if (context->getClientVersion() < ES_3_1)
1094 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001095 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001096 return false;
1097 }
1098
Geoff Lange8afa902017-09-27 15:00:43 -04001099 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001100 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001101 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001102 return false;
1103 }
1104
1105 switch (pname)
1106 {
1107 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1108 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1109 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1110 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1111 break;
Jiawei Shaob1e91382018-05-17 14:33:55 +08001112 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1113 if (!context->getExtensions().geometryShader)
1114 {
1115 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1116 return false;
1117 }
1118 break;
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001119 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001120 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001121 return false;
1122 }
1123
1124 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1125 ASSERT(framebuffer);
1126
1127 if (framebuffer->id() == 0)
1128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001129 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001130 return false;
1131 }
1132 return true;
1133}
1134
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001135bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1136 GLenum target,
1137 GLenum pname,
1138 GLsizei bufSize,
1139 GLsizei *length,
1140 GLint *params)
1141{
1142 UNIMPLEMENTED();
1143 return false;
1144}
1145
jchen1015015f72017-03-16 13:54:21 +08001146bool ValidateGetProgramResourceIndex(Context *context,
1147 GLuint program,
1148 GLenum programInterface,
1149 const GLchar *name)
1150{
1151 if (context->getClientVersion() < ES_3_1)
1152 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen1015015f72017-03-16 13:54:21 +08001154 return false;
1155 }
1156
1157 Program *programObject = GetValidProgram(context, program);
1158 if (programObject == nullptr)
1159 {
1160 return false;
1161 }
1162
1163 if (!ValidateNamedProgramInterface(programInterface))
1164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001165 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1166 << std::uppercase << programInterface);
jchen1015015f72017-03-16 13:54:21 +08001167 return false;
1168 }
Shao80957d92017-02-20 21:25:59 +08001169
1170 return true;
1171}
1172
Jamie Madill5b772312018-03-08 20:28:32 -05001173bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001174 GLuint bindingIndex,
1175 GLuint buffer,
1176 GLintptr offset,
1177 GLsizei stride)
1178{
1179 if (context->getClientVersion() < ES_3_1)
1180 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001181 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001182 return false;
1183 }
1184
1185 if (!context->isBufferGenerated(buffer))
1186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001187 context->handleError(InvalidOperation() << "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001188 return false;
1189 }
1190
1191 const Caps &caps = context->getCaps();
1192 if (bindingIndex >= caps.maxVertexAttribBindings)
1193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001194 context->handleError(InvalidValue()
1195 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001196 return false;
1197 }
1198
1199 if (offset < 0)
1200 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001201 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001202 return false;
1203 }
1204
1205 if (stride < 0 || stride > caps.maxVertexAttribStride)
1206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001207 context->handleError(InvalidValue()
1208 << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001209 return false;
1210 }
1211
1212 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1213 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1214 if (context->getGLState().getVertexArrayId() == 0)
1215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001216 context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001217 return false;
1218 }
1219
1220 return true;
1221}
1222
Jamie Madill5b772312018-03-08 20:28:32 -05001223bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001224{
1225 if (context->getClientVersion() < ES_3_1)
1226 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001227 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001228 return false;
1229 }
1230
1231 const Caps &caps = context->getCaps();
1232 if (bindingIndex >= caps.maxVertexAttribBindings)
1233 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001234 context->handleError(InvalidValue()
1235 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001236 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->getGLState().getVertexArrayId() == 0)
1242 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001243 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001244 return false;
1245 }
1246
1247 return true;
1248}
1249
Jamie Madill5b772312018-03-08 20:28:32 -05001250bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001251 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001252 GLint size,
1253 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001254 GLboolean normalized,
1255 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001256{
Jiajia Qin5451d532017-11-16 17:16:34 +08001257 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1258 false);
1259}
Shao80957d92017-02-20 21:25:59 +08001260
Jamie Madill5b772312018-03-08 20:28:32 -05001261bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001262 GLuint attribindex,
1263 GLint size,
1264 GLenum type,
1265 GLuint relativeoffset)
1266{
1267 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001268}
1269
Jamie Madill5b772312018-03-08 20:28:32 -05001270bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001271{
1272 if (context->getClientVersion() < ES_3_1)
1273 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001274 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001275 return false;
1276 }
1277
1278 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1279 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1280 if (context->getGLState().getVertexArrayId() == 0)
1281 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001282 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001283 return false;
1284 }
1285
1286 const Caps &caps = context->getCaps();
1287 if (attribIndex >= caps.maxVertexAttributes)
1288 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001289 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001290 return false;
1291 }
1292
1293 if (bindingIndex >= caps.maxVertexAttribBindings)
1294 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001295 context->handleError(InvalidValue()
1296 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001297 return false;
1298 }
1299
jchen1015015f72017-03-16 13:54:21 +08001300 return true;
1301}
1302
jchen10fd7c3b52017-03-21 15:36:03 +08001303bool ValidateGetProgramResourceName(Context *context,
1304 GLuint program,
1305 GLenum programInterface,
1306 GLuint index,
1307 GLsizei bufSize,
1308 GLsizei *length,
1309 GLchar *name)
1310{
1311 if (context->getClientVersion() < ES_3_1)
1312 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001314 return false;
1315 }
1316
1317 Program *programObject = GetValidProgram(context, program);
1318 if (programObject == nullptr)
1319 {
1320 return false;
1321 }
1322
1323 if (!ValidateNamedProgramInterface(programInterface))
1324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001325 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1326 << std::uppercase << programInterface);
jchen10fd7c3b52017-03-21 15:36:03 +08001327 return false;
1328 }
1329
1330 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1331 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001332 context->handleError(InvalidValue() << "Invalid index: " << index);
jchen10fd7c3b52017-03-21 15:36:03 +08001333 return false;
1334 }
1335
1336 if (bufSize < 0)
1337 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001338 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001339 return false;
1340 }
1341
1342 return true;
1343}
1344
Xinghua Cao2b396592017-03-29 15:36:04 +08001345bool ValidateDispatchCompute(Context *context,
1346 GLuint numGroupsX,
1347 GLuint numGroupsY,
1348 GLuint numGroupsZ)
1349{
1350 if (context->getClientVersion() < ES_3_1)
1351 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001352 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001353 return false;
1354 }
1355
1356 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001357 Program *program = state.getLinkedProgram(context);
Xinghua Cao2b396592017-03-29 15:36:04 +08001358
Jiawei Shao385b3e02018-03-21 09:43:28 +08001359 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001360 {
Qin Jiajia62fcf622017-11-30 16:16:12 +08001361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001362 return false;
1363 }
1364
1365 const Caps &caps = context->getCaps();
1366 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1367 {
1368 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001369 InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
1370 << caps.maxComputeWorkGroupCount[0]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001371 return false;
1372 }
1373 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1374 {
1375 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001376 InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]="
1377 << caps.maxComputeWorkGroupCount[1]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001378 return false;
1379 }
1380 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1381 {
1382 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001383 InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
1384 << caps.maxComputeWorkGroupCount[2]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001385 return false;
1386 }
1387
1388 return true;
1389}
1390
Jiajia Qin5451d532017-11-16 17:16:34 +08001391bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1392{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001393 if (context->getClientVersion() < ES_3_1)
1394 {
1395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1396 return false;
1397 }
1398
1399 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001400 Program *program = state.getLinkedProgram(context);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001401
Jiawei Shao385b3e02018-03-21 09:43:28 +08001402 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001403 {
1404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
1405 return false;
1406 }
1407
Qin Jiajia62fcf622017-11-30 16:16:12 +08001408 if (indirect < 0)
1409 {
1410 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
1411 return false;
1412 }
1413
1414 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1415 {
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001416 ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
1417 return false;
1418 }
1419
Jamie Madill5b772312018-03-08 20:28:32 -05001420 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001421 if (!dispatchIndirectBuffer)
1422 {
1423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001424 return false;
1425 }
1426
1427 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1428 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1429 if (!checkedSum.IsValid() ||
1430 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1431 {
1432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
1433 return false;
1434 }
1435
1436 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001437}
1438
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001439bool ValidateBindImageTexture(Context *context,
1440 GLuint unit,
1441 GLuint texture,
1442 GLint level,
1443 GLboolean layered,
1444 GLint layer,
1445 GLenum access,
1446 GLenum format)
1447{
1448 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1449 if (unit >= maxImageUnits)
1450 {
1451 context->handleError(InvalidValue()
1452 << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = "
1453 << maxImageUnits);
1454 return false;
1455 }
1456
1457 if (level < 0)
1458 {
1459 context->handleError(InvalidValue() << "level is negative.");
1460 return false;
1461 }
1462
1463 if (layer < 0)
1464 {
1465 context->handleError(InvalidValue() << "layer is negative.");
1466 return false;
1467 }
1468
1469 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1470 {
1471 context->handleError(InvalidEnum() << "access is not one of the supported tokens.");
1472 return false;
1473 }
1474
1475 switch (format)
1476 {
1477 case GL_RGBA32F:
1478 case GL_RGBA16F:
1479 case GL_R32F:
1480 case GL_RGBA32UI:
1481 case GL_RGBA16UI:
1482 case GL_RGBA8UI:
1483 case GL_R32UI:
1484 case GL_RGBA32I:
1485 case GL_RGBA16I:
1486 case GL_RGBA8I:
1487 case GL_R32I:
1488 case GL_RGBA8:
1489 case GL_RGBA8_SNORM:
1490 break;
1491 default:
1492 context->handleError(InvalidValue()
1493 << "format is not one of supported image unit formats.");
1494 return false;
1495 }
1496
1497 if (texture != 0)
1498 {
1499 Texture *tex = context->getTexture(texture);
1500
1501 if (tex == nullptr)
1502 {
1503 context->handleError(InvalidValue()
1504 << "texture is not the name of an existing texture object.");
1505 return false;
1506 }
1507
1508 if (!tex->getImmutableFormat())
1509 {
1510 context->handleError(InvalidOperation()
1511 << "texture is not the name of an immutable texture object.");
1512 return false;
1513 }
1514 }
1515
1516 return true;
1517}
jchen10191381f2017-04-11 13:59:04 +08001518
1519bool ValidateGetProgramResourceLocation(Context *context,
1520 GLuint program,
1521 GLenum programInterface,
1522 const GLchar *name)
1523{
1524 if (context->getClientVersion() < ES_3_1)
1525 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10191381f2017-04-11 13:59:04 +08001527 return false;
1528 }
1529
1530 Program *programObject = GetValidProgram(context, program);
1531 if (programObject == nullptr)
1532 {
1533 return false;
1534 }
1535
1536 if (!programObject->isLinked())
1537 {
1538 context->handleError(InvalidOperation() << "Program is not successfully linked.");
1539 return false;
1540 }
1541
1542 if (!ValidateLocationProgramInterface(programInterface))
1543 {
1544 context->handleError(InvalidEnum() << "Invalid program interface.");
1545 return false;
1546 }
1547 return true;
1548}
1549
jchen10880683b2017-04-12 16:21:55 +08001550bool ValidateGetProgramResourceiv(Context *context,
1551 GLuint program,
1552 GLenum programInterface,
1553 GLuint index,
1554 GLsizei propCount,
1555 const GLenum *props,
1556 GLsizei bufSize,
1557 GLsizei *length,
1558 GLint *params)
1559{
1560 if (context->getClientVersion() < ES_3_1)
1561 {
jchen10d9cd7b72017-08-30 15:04:25 +08001562 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10880683b2017-04-12 16:21:55 +08001563 return false;
1564 }
1565
1566 Program *programObject = GetValidProgram(context, program);
1567 if (programObject == nullptr)
1568 {
1569 return false;
1570 }
1571 if (!ValidateProgramInterface(programInterface))
1572 {
1573 context->handleError(InvalidEnum() << "Invalid program interface.");
1574 return false;
1575 }
1576 if (propCount <= 0)
1577 {
1578 context->handleError(InvalidValue() << "Invalid propCount.");
1579 return false;
1580 }
1581 if (bufSize < 0)
1582 {
1583 context->handleError(InvalidValue() << "Invalid bufSize.");
1584 return false;
1585 }
1586 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1587 {
1588 context->handleError(InvalidValue() << "Invalid index: " << index);
1589 return false;
1590 }
1591 for (GLsizei i = 0; i < propCount; i++)
1592 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001593 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001594 {
1595 context->handleError(InvalidEnum() << "Invalid prop.");
1596 return false;
1597 }
1598 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1599 {
1600 context->handleError(InvalidOperation() << "Not an allowed prop for interface");
1601 return false;
1602 }
1603 }
1604 return true;
1605}
1606
jchen10d9cd7b72017-08-30 15:04:25 +08001607bool ValidateGetProgramInterfaceiv(Context *context,
1608 GLuint program,
1609 GLenum programInterface,
1610 GLenum pname,
1611 GLint *params)
1612{
1613 if (context->getClientVersion() < ES_3_1)
1614 {
1615 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1616 return false;
1617 }
1618
1619 Program *programObject = GetValidProgram(context, program);
1620 if (programObject == nullptr)
1621 {
1622 return false;
1623 }
1624
1625 if (!ValidateProgramInterface(programInterface))
1626 {
1627 context->handleError(InvalidEnum() << "Invalid program interface.");
1628 return false;
1629 }
1630
1631 switch (pname)
1632 {
1633 case GL_ACTIVE_RESOURCES:
1634 case GL_MAX_NAME_LENGTH:
1635 case GL_MAX_NUM_ACTIVE_VARIABLES:
1636 break;
1637
1638 default:
1639 context->handleError(InvalidEnum() << "Unknown property of program interface.");
1640 return false;
1641 }
1642
1643 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1644 {
1645 context->handleError(InvalidOperation()
1646 << "Active atomic counter resources are not assigned name strings.");
1647 return false;
1648 }
1649
1650 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1651 {
1652 switch (programInterface)
1653 {
1654 case GL_ATOMIC_COUNTER_BUFFER:
1655 case GL_SHADER_STORAGE_BLOCK:
1656 case GL_UNIFORM_BLOCK:
1657 break;
1658
1659 default:
1660 context->handleError(
1661 InvalidOperation()
1662 << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
1663 return false;
1664 }
1665 }
1666
1667 return true;
1668}
1669
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001670bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1671 GLuint program,
1672 GLenum programInterface,
1673 GLenum pname,
1674 GLsizei bufSize,
1675 GLsizei *length,
1676 GLint *params)
1677{
1678 UNIMPLEMENTED();
1679 return false;
1680}
1681
Yunchao Hea336b902017-08-02 16:05:21 +08001682static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1683{
1684 if (context->getClientVersion() < ES_3_1)
1685 {
1686 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1687 return false;
1688 }
1689
1690 return ValidateGenOrDelete(context, n);
1691}
1692
1693bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1694{
1695 return ValidateGenOrDeleteES31(context, n);
1696}
1697
1698bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1699{
1700 return ValidateGenOrDeleteES31(context, n);
1701}
1702
1703bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1704{
1705 if (context->getClientVersion() < ES_3_1)
1706 {
1707 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1708 return false;
1709 }
1710
1711 if (!context->isProgramPipelineGenerated(pipeline))
1712 {
1713 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
1714 return false;
1715 }
1716
1717 return true;
1718}
1719
1720bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1721{
1722 if (context->getClientVersion() < ES_3_1)
1723 {
1724 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1725 return false;
1726 }
1727
1728 return true;
1729}
1730
Jiajia Qin5451d532017-11-16 17:16:34 +08001731bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1732{
1733 UNIMPLEMENTED();
1734 return false;
1735}
1736
1737bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1738{
1739 UNIMPLEMENTED();
1740 return false;
1741}
1742
1743bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001744 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001745 GLsizei count,
1746 const GLchar *const *strings)
1747{
1748 UNIMPLEMENTED();
1749 return false;
1750}
1751
1752bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1753{
1754 UNIMPLEMENTED();
1755 return false;
1756}
1757
1758bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1759{
1760 UNIMPLEMENTED();
1761 return false;
1762}
1763
1764bool ValidateGetProgramPipelineInfoLog(Context *context,
1765 GLuint pipeline,
1766 GLsizei bufSize,
1767 GLsizei *length,
1768 GLchar *infoLog)
1769{
1770 UNIMPLEMENTED();
1771 return false;
1772}
1773
1774bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1775{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001776 if (context->getClientVersion() < ES_3_1)
1777 {
1778 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1779 return false;
1780 }
1781
1782 if (barriers == GL_ALL_BARRIER_BITS)
1783 {
1784 return true;
1785 }
1786
1787 GLbitfield supported_barrier_bits =
1788 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1789 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1790 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1791 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1792 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1793 if ((barriers & ~supported_barrier_bits) != 0)
1794 {
1795 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1796 return false;
1797 }
1798
1799 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001800}
1801
1802bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1803{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001804 if (context->getClientVersion() < ES_3_1)
1805 {
1806 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1807 return false;
1808 }
1809
1810 if (barriers == GL_ALL_BARRIER_BITS)
1811 {
1812 return true;
1813 }
1814
1815 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1816 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1817 GL_SHADER_STORAGE_BARRIER_BIT |
1818 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1819 if ((barriers & ~supported_barrier_bits) != 0)
1820 {
1821 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1822 return false;
1823 }
1824
1825 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001826}
1827
1828bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001829{
1830 if (context->getClientVersion() < ES_3_1)
1831 {
1832 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1833 return false;
1834 }
1835
1836 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1837 {
1838 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
1839 return false;
1840 }
1841
1842 return true;
1843}
1844
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001845bool ValidateFramebufferTextureEXT(Context *context,
1846 GLenum target,
1847 GLenum attachment,
1848 GLuint texture,
1849 GLint level)
1850{
1851 if (!context->getExtensions().geometryShader)
1852 {
1853 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GeometryShaderExtensionNotEnabled);
1854 return false;
1855 }
1856
1857 if (texture != 0)
1858 {
1859 gl::Texture *tex = context->getTexture(texture);
1860
1861 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
1862 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
1863 // We put this validation before ValidateFramebufferTextureBase because it is an
1864 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
1865 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
1866 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
1867 // existing texture object of type matching textarget.
1868 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
1869 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
1870 // three-dimensional or two-dimensional array texture.
1871 if (tex == nullptr)
1872 {
1873 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureName);
1874 return false;
1875 }
1876
1877 if (!ValidMipLevel(context, tex->getType(), level))
1878 {
1879 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1880 return false;
1881 }
1882 }
1883
1884 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1885 {
1886 return false;
1887 }
1888
1889 return true;
1890}
1891
Olli Etuaho064458a2018-08-30 14:02:02 +03001892// GL_OES_texture_storage_multisample_2d_array
1893bool ValidateTexStorage3DMultisampleOES(Context *context,
1894 TextureType target,
1895 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05001896 GLenum sizedinternalformat,
Olli Etuaho064458a2018-08-30 14:02:02 +03001897 GLsizei width,
1898 GLsizei height,
1899 GLsizei depth,
1900 GLboolean fixedsamplelocations)
Olli Etuaho89664842018-08-24 14:45:36 +03001901{
Olli Etuaho064458a2018-08-30 14:02:02 +03001902 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03001903 {
1904 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1905 return false;
1906 }
1907
1908 if (target != TextureType::_2DMultisampleArray)
1909 {
Olli Etuaho064458a2018-08-30 14:02:02 +03001910 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TargetMustBeTexture2DMultisampleArrayOES);
Olli Etuahod310a432018-08-24 15:40:23 +03001911 return false;
1912 }
1913
1914 if (width < 1 || height < 1 || depth < 1)
1915 {
1916 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
1917 return false;
1918 }
1919
1920 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
1921 height);
Olli Etuaho89664842018-08-24 14:45:36 +03001922}
1923
Olli Etuaho0ca09752018-09-24 11:00:50 +03001924bool ValidateGetProgramResourceLocationIndexEXT(Context *context,
1925 GLuint program,
1926 GLenum programInterface,
1927 const char *name)
1928{
1929 if (!context->getExtensions().blendFuncExtended)
1930 {
1931 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
1932 return false;
1933 }
1934 if (context->getClientVersion() < ES_3_1)
1935 {
1936 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1937 return false;
1938 }
1939 if (programInterface != GL_PROGRAM_OUTPUT)
1940 {
1941 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ProgramInterfaceMustBeProgramOutput);
1942 return false;
1943 }
1944 Program *programObject = GetValidProgram(context, program);
1945 if (!programObject)
1946 {
1947 return false;
1948 }
1949 if (!programObject->isLinked())
1950 {
1951 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
1952 return false;
1953 }
1954 return true;
1955}
1956
Martin Radev66fb8202016-07-28 11:45:20 +03001957} // namespace gl