blob: 8223433d814931cfec80467bb6d12be524a06e10 [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
Martin Radev66fb8202016-07-28 11:45:20 +03009#include "libANGLE/validationES31.h"
10
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"
Yunchao Hea336b902017-08-02 16:05:21 +080016#include "libANGLE/validationES2.h"
Geoff Lang2e43dbb2016-10-14 12:27:35 -040017#include "libANGLE/validationES3.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();
540 Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
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
He Yunchao11b038b2016-11-22 21:24:04 +0800894bool ValidateGetTexLevelParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800895 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800896 GLint level,
897 GLenum pname,
898 GLsizei *length)
899{
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
906 if (length)
907 {
908 *length = 0;
909 }
910
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800911 TextureType type = TextureTargetToType(target);
912
913 if (!ValidTexLevelDestinationTarget(context, type))
He Yunchao11b038b2016-11-22 21:24:04 +0800914 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700915 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
He Yunchao11b038b2016-11-22 21:24:04 +0800916 return false;
917 }
918
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800919 if (context->getTargetTexture(type) == nullptr)
He Yunchao11b038b2016-11-22 21:24:04 +0800920 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500921 context->handleError(InvalidEnum() << "No texture bound.");
He Yunchao11b038b2016-11-22 21:24:04 +0800922 return false;
923 }
924
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800925 if (!ValidMipLevel(context, type, level))
He Yunchao11b038b2016-11-22 21:24:04 +0800926 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500927 context->handleError(InvalidValue());
He Yunchao11b038b2016-11-22 21:24:04 +0800928 return false;
929 }
930
931 switch (pname)
932 {
933 case GL_TEXTURE_RED_TYPE:
934 case GL_TEXTURE_GREEN_TYPE:
935 case GL_TEXTURE_BLUE_TYPE:
936 case GL_TEXTURE_ALPHA_TYPE:
937 case GL_TEXTURE_DEPTH_TYPE:
938 break;
939 case GL_TEXTURE_RED_SIZE:
940 case GL_TEXTURE_GREEN_SIZE:
941 case GL_TEXTURE_BLUE_SIZE:
942 case GL_TEXTURE_ALPHA_SIZE:
943 case GL_TEXTURE_DEPTH_SIZE:
944 case GL_TEXTURE_STENCIL_SIZE:
945 case GL_TEXTURE_SHARED_SIZE:
946 break;
947 case GL_TEXTURE_INTERNAL_FORMAT:
948 case GL_TEXTURE_WIDTH:
949 case GL_TEXTURE_HEIGHT:
950 case GL_TEXTURE_DEPTH:
951 break;
952 case GL_TEXTURE_SAMPLES:
953 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
954 break;
955 case GL_TEXTURE_COMPRESSED:
956 break;
957 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700958 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
He Yunchao11b038b2016-11-22 21:24:04 +0800959 return false;
960 }
961
962 if (length)
963 {
964 *length = 1;
965 }
966 return true;
967}
968
969bool ValidateGetTexLevelParameterfv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800970 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800971 GLint level,
972 GLenum pname,
973 GLfloat *params)
974{
975 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
976}
977
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700978bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
979 TextureTarget target,
980 GLint level,
981 GLenum pname,
982 GLsizei bufSize,
983 GLsizei *length,
984 GLfloat *params)
985{
986 UNIMPLEMENTED();
987 return false;
988}
989
He Yunchao11b038b2016-11-22 21:24:04 +0800990bool ValidateGetTexLevelParameteriv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800991 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800992 GLint level,
993 GLenum pname,
994 GLint *params)
995{
996 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
997}
998
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700999bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
1000 TextureTarget target,
1001 GLint level,
1002 GLenum pname,
1003 GLsizei bufSize,
1004 GLsizei *length,
1005 GLint *params)
1006{
1007 UNIMPLEMENTED();
1008 return false;
1009}
1010
Jiajia Qin5451d532017-11-16 17:16:34 +08001011bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001012 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +08001013 GLsizei samples,
1014 GLint internalFormat,
1015 GLsizei width,
1016 GLsizei height,
1017 GLboolean fixedSampleLocations)
1018{
1019 if (context->getClientVersion() < ES_3_1)
1020 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001022 return false;
1023 }
1024
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001025 if (target != TextureType::_2DMultisample)
JiangYizhoubddc46b2016-12-09 09:50:51 +08001026 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001027 context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001028 return false;
1029 }
1030
1031 if (width < 1 || height < 1)
1032 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001033 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001034 return false;
1035 }
1036
Olli Etuahod310a432018-08-24 15:40:23 +03001037 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001038}
1039
1040bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
1041{
1042 if (context->getClientVersion() < ES_3_1)
1043 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001044 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001045 return false;
1046 }
1047
1048 if (pname != GL_SAMPLE_POSITION)
1049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001050 context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001051 return false;
1052 }
1053
JiangYizhou5b03f472017-01-09 10:22:53 +08001054 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04001055 GLint samples = framebuffer->getSamples(context);
JiangYizhou5b03f472017-01-09 10:22:53 +08001056
Jamie Madille98b1b52018-03-08 09:47:23 -05001057 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +08001058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001059 context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001060 return false;
1061 }
1062
1063 return true;
1064}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001065
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001066bool ValidateGetMultisamplefvRobustANGLE(Context *context,
1067 GLenum pname,
1068 GLuint index,
1069 GLsizei bufSize,
1070 GLsizei *length,
1071 GLfloat *val)
1072{
1073 UNIMPLEMENTED();
1074 return false;
1075}
1076
Jiajia Qin5451d532017-11-16 17:16:34 +08001077bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001078{
1079 if (context->getClientVersion() < ES_3_1)
1080 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001081 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001082 return false;
1083 }
1084
Geoff Lange8afa902017-09-27 15:00:43 -04001085 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001087 context->handleError(InvalidEnum() << "Invalid framebuffer target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001088 return false;
1089 }
1090
1091 switch (pname)
1092 {
1093 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1094 {
1095 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1096 if (param < 0 || param > maxWidth)
1097 {
1098 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001099 InvalidValue()
1100 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001101 return false;
1102 }
1103 break;
1104 }
1105 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1106 {
1107 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1108 if (param < 0 || param > maxHeight)
1109 {
1110 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001111 InvalidValue()
1112 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001113 return false;
1114 }
1115 break;
1116 }
1117 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1118 {
1119 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1120 if (param < 0 || param > maxSamples)
1121 {
1122 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001123 InvalidValue()
1124 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001125 return false;
1126 }
1127 break;
1128 }
1129 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1130 {
1131 break;
1132 }
Jiawei Shaob1e91382018-05-17 14:33:55 +08001133 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1134 {
1135 if (!context->getExtensions().geometryShader)
1136 {
1137 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1138 return false;
1139 }
1140 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1141 if (param < 0 || param > maxLayers)
1142 {
1143 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferLayer);
1144 return false;
1145 }
1146 break;
1147 }
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001148 default:
1149 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001150 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001151 return false;
1152 }
1153 }
1154
1155 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1156 ASSERT(framebuffer);
1157 if (framebuffer->id() == 0)
1158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001159 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001160 return false;
1161 }
1162 return true;
1163}
1164
Jiajia Qin5451d532017-11-16 17:16:34 +08001165bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001166{
1167 if (context->getClientVersion() < ES_3_1)
1168 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001169 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001170 return false;
1171 }
1172
Geoff Lange8afa902017-09-27 15:00:43 -04001173 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001174 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001175 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001176 return false;
1177 }
1178
1179 switch (pname)
1180 {
1181 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1182 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1183 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1184 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1185 break;
Jiawei Shaob1e91382018-05-17 14:33:55 +08001186 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1187 if (!context->getExtensions().geometryShader)
1188 {
1189 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1190 return false;
1191 }
1192 break;
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001193 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001194 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001195 return false;
1196 }
1197
1198 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1199 ASSERT(framebuffer);
1200
1201 if (framebuffer->id() == 0)
1202 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001203 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001204 return false;
1205 }
1206 return true;
1207}
1208
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001209bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1210 GLenum target,
1211 GLenum pname,
1212 GLsizei bufSize,
1213 GLsizei *length,
1214 GLint *params)
1215{
1216 UNIMPLEMENTED();
1217 return false;
1218}
1219
jchen1015015f72017-03-16 13:54:21 +08001220bool ValidateGetProgramResourceIndex(Context *context,
1221 GLuint program,
1222 GLenum programInterface,
1223 const GLchar *name)
1224{
1225 if (context->getClientVersion() < ES_3_1)
1226 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001227 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen1015015f72017-03-16 13:54:21 +08001228 return false;
1229 }
1230
1231 Program *programObject = GetValidProgram(context, program);
1232 if (programObject == nullptr)
1233 {
1234 return false;
1235 }
1236
1237 if (!ValidateNamedProgramInterface(programInterface))
1238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001239 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1240 << std::uppercase << programInterface);
jchen1015015f72017-03-16 13:54:21 +08001241 return false;
1242 }
Shao80957d92017-02-20 21:25:59 +08001243
1244 return true;
1245}
1246
Jamie Madill5b772312018-03-08 20:28:32 -05001247bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001248 GLuint bindingIndex,
1249 GLuint buffer,
1250 GLintptr offset,
1251 GLsizei stride)
1252{
1253 if (context->getClientVersion() < ES_3_1)
1254 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001255 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001256 return false;
1257 }
1258
1259 if (!context->isBufferGenerated(buffer))
1260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001261 context->handleError(InvalidOperation() << "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001262 return false;
1263 }
1264
1265 const Caps &caps = context->getCaps();
1266 if (bindingIndex >= caps.maxVertexAttribBindings)
1267 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001268 context->handleError(InvalidValue()
1269 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001270 return false;
1271 }
1272
1273 if (offset < 0)
1274 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001275 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001276 return false;
1277 }
1278
1279 if (stride < 0 || stride > caps.maxVertexAttribStride)
1280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001281 context->handleError(InvalidValue()
1282 << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001283 return false;
1284 }
1285
1286 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1287 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1288 if (context->getGLState().getVertexArrayId() == 0)
1289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001290 context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001291 return false;
1292 }
1293
1294 return true;
1295}
1296
Jamie Madill5b772312018-03-08 20:28:32 -05001297bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001298{
1299 if (context->getClientVersion() < ES_3_1)
1300 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001302 return false;
1303 }
1304
1305 const Caps &caps = context->getCaps();
1306 if (bindingIndex >= caps.maxVertexAttribBindings)
1307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001308 context->handleError(InvalidValue()
1309 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001310 return false;
1311 }
1312
1313 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1314 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1315 if (context->getGLState().getVertexArrayId() == 0)
1316 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001317 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001318 return false;
1319 }
1320
1321 return true;
1322}
1323
Jamie Madill5b772312018-03-08 20:28:32 -05001324bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001325 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001326 GLint size,
1327 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001328 GLboolean normalized,
1329 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001330{
Jiajia Qin5451d532017-11-16 17:16:34 +08001331 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1332 false);
1333}
Shao80957d92017-02-20 21:25:59 +08001334
Jamie Madill5b772312018-03-08 20:28:32 -05001335bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001336 GLuint attribindex,
1337 GLint size,
1338 GLenum type,
1339 GLuint relativeoffset)
1340{
1341 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001342}
1343
Jamie Madill5b772312018-03-08 20:28:32 -05001344bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001345{
1346 if (context->getClientVersion() < ES_3_1)
1347 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001348 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001349 return false;
1350 }
1351
1352 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1353 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1354 if (context->getGLState().getVertexArrayId() == 0)
1355 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001356 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001357 return false;
1358 }
1359
1360 const Caps &caps = context->getCaps();
1361 if (attribIndex >= caps.maxVertexAttributes)
1362 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001363 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001364 return false;
1365 }
1366
1367 if (bindingIndex >= caps.maxVertexAttribBindings)
1368 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001369 context->handleError(InvalidValue()
1370 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001371 return false;
1372 }
1373
jchen1015015f72017-03-16 13:54:21 +08001374 return true;
1375}
1376
jchen10fd7c3b52017-03-21 15:36:03 +08001377bool ValidateGetProgramResourceName(Context *context,
1378 GLuint program,
1379 GLenum programInterface,
1380 GLuint index,
1381 GLsizei bufSize,
1382 GLsizei *length,
1383 GLchar *name)
1384{
1385 if (context->getClientVersion() < ES_3_1)
1386 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001388 return false;
1389 }
1390
1391 Program *programObject = GetValidProgram(context, program);
1392 if (programObject == nullptr)
1393 {
1394 return false;
1395 }
1396
1397 if (!ValidateNamedProgramInterface(programInterface))
1398 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001399 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1400 << std::uppercase << programInterface);
jchen10fd7c3b52017-03-21 15:36:03 +08001401 return false;
1402 }
1403
1404 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1405 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001406 context->handleError(InvalidValue() << "Invalid index: " << index);
jchen10fd7c3b52017-03-21 15:36:03 +08001407 return false;
1408 }
1409
1410 if (bufSize < 0)
1411 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001412 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001413 return false;
1414 }
1415
1416 return true;
1417}
1418
Xinghua Cao2b396592017-03-29 15:36:04 +08001419bool ValidateDispatchCompute(Context *context,
1420 GLuint numGroupsX,
1421 GLuint numGroupsY,
1422 GLuint numGroupsZ)
1423{
1424 if (context->getClientVersion() < ES_3_1)
1425 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001426 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001427 return false;
1428 }
1429
1430 const State &state = context->getGLState();
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001431 Program *program = state.getLinkedProgram();
Xinghua Cao2b396592017-03-29 15:36:04 +08001432
Jiawei Shao385b3e02018-03-21 09:43:28 +08001433 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001434 {
Qin Jiajia62fcf622017-11-30 16:16:12 +08001435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001436 return false;
1437 }
1438
1439 const Caps &caps = context->getCaps();
1440 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1441 {
1442 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001443 InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
1444 << caps.maxComputeWorkGroupCount[0]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001445 return false;
1446 }
1447 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1448 {
1449 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001450 InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]="
1451 << caps.maxComputeWorkGroupCount[1]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001452 return false;
1453 }
1454 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1455 {
1456 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001457 InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
1458 << caps.maxComputeWorkGroupCount[2]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001459 return false;
1460 }
1461
1462 return true;
1463}
1464
Jiajia Qin5451d532017-11-16 17:16:34 +08001465bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1466{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001467 if (context->getClientVersion() < ES_3_1)
1468 {
1469 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1470 return false;
1471 }
1472
1473 const State &state = context->getGLState();
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001474 Program *program = state.getLinkedProgram();
Qin Jiajia62fcf622017-11-30 16:16:12 +08001475
Jiawei Shao385b3e02018-03-21 09:43:28 +08001476 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001477 {
1478 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
1479 return false;
1480 }
1481
Qin Jiajia62fcf622017-11-30 16:16:12 +08001482 if (indirect < 0)
1483 {
1484 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
1485 return false;
1486 }
1487
1488 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1489 {
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001490 ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
1491 return false;
1492 }
1493
Jamie Madill5b772312018-03-08 20:28:32 -05001494 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001495 if (!dispatchIndirectBuffer)
1496 {
1497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001498 return false;
1499 }
1500
1501 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1502 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1503 if (!checkedSum.IsValid() ||
1504 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1505 {
1506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
1507 return false;
1508 }
1509
1510 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001511}
1512
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001513bool ValidateBindImageTexture(Context *context,
1514 GLuint unit,
1515 GLuint texture,
1516 GLint level,
1517 GLboolean layered,
1518 GLint layer,
1519 GLenum access,
1520 GLenum format)
1521{
1522 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1523 if (unit >= maxImageUnits)
1524 {
1525 context->handleError(InvalidValue()
1526 << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = "
1527 << maxImageUnits);
1528 return false;
1529 }
1530
1531 if (level < 0)
1532 {
1533 context->handleError(InvalidValue() << "level is negative.");
1534 return false;
1535 }
1536
1537 if (layer < 0)
1538 {
1539 context->handleError(InvalidValue() << "layer is negative.");
1540 return false;
1541 }
1542
1543 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1544 {
1545 context->handleError(InvalidEnum() << "access is not one of the supported tokens.");
1546 return false;
1547 }
1548
1549 switch (format)
1550 {
1551 case GL_RGBA32F:
1552 case GL_RGBA16F:
1553 case GL_R32F:
1554 case GL_RGBA32UI:
1555 case GL_RGBA16UI:
1556 case GL_RGBA8UI:
1557 case GL_R32UI:
1558 case GL_RGBA32I:
1559 case GL_RGBA16I:
1560 case GL_RGBA8I:
1561 case GL_R32I:
1562 case GL_RGBA8:
1563 case GL_RGBA8_SNORM:
1564 break;
1565 default:
1566 context->handleError(InvalidValue()
1567 << "format is not one of supported image unit formats.");
1568 return false;
1569 }
1570
1571 if (texture != 0)
1572 {
1573 Texture *tex = context->getTexture(texture);
1574
1575 if (tex == nullptr)
1576 {
1577 context->handleError(InvalidValue()
1578 << "texture is not the name of an existing texture object.");
1579 return false;
1580 }
1581
1582 if (!tex->getImmutableFormat())
1583 {
1584 context->handleError(InvalidOperation()
1585 << "texture is not the name of an immutable texture object.");
1586 return false;
1587 }
1588 }
1589
1590 return true;
1591}
jchen10191381f2017-04-11 13:59:04 +08001592
1593bool ValidateGetProgramResourceLocation(Context *context,
1594 GLuint program,
1595 GLenum programInterface,
1596 const GLchar *name)
1597{
1598 if (context->getClientVersion() < ES_3_1)
1599 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001600 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10191381f2017-04-11 13:59:04 +08001601 return false;
1602 }
1603
1604 Program *programObject = GetValidProgram(context, program);
1605 if (programObject == nullptr)
1606 {
1607 return false;
1608 }
1609
1610 if (!programObject->isLinked())
1611 {
1612 context->handleError(InvalidOperation() << "Program is not successfully linked.");
1613 return false;
1614 }
1615
1616 if (!ValidateLocationProgramInterface(programInterface))
1617 {
1618 context->handleError(InvalidEnum() << "Invalid program interface.");
1619 return false;
1620 }
1621 return true;
1622}
1623
jchen10880683b2017-04-12 16:21:55 +08001624bool ValidateGetProgramResourceiv(Context *context,
1625 GLuint program,
1626 GLenum programInterface,
1627 GLuint index,
1628 GLsizei propCount,
1629 const GLenum *props,
1630 GLsizei bufSize,
1631 GLsizei *length,
1632 GLint *params)
1633{
1634 if (context->getClientVersion() < ES_3_1)
1635 {
jchen10d9cd7b72017-08-30 15:04:25 +08001636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10880683b2017-04-12 16:21:55 +08001637 return false;
1638 }
1639
1640 Program *programObject = GetValidProgram(context, program);
1641 if (programObject == nullptr)
1642 {
1643 return false;
1644 }
1645 if (!ValidateProgramInterface(programInterface))
1646 {
1647 context->handleError(InvalidEnum() << "Invalid program interface.");
1648 return false;
1649 }
1650 if (propCount <= 0)
1651 {
1652 context->handleError(InvalidValue() << "Invalid propCount.");
1653 return false;
1654 }
1655 if (bufSize < 0)
1656 {
1657 context->handleError(InvalidValue() << "Invalid bufSize.");
1658 return false;
1659 }
1660 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1661 {
1662 context->handleError(InvalidValue() << "Invalid index: " << index);
1663 return false;
1664 }
1665 for (GLsizei i = 0; i < propCount; i++)
1666 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001667 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001668 {
1669 context->handleError(InvalidEnum() << "Invalid prop.");
1670 return false;
1671 }
1672 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1673 {
1674 context->handleError(InvalidOperation() << "Not an allowed prop for interface");
1675 return false;
1676 }
1677 }
1678 return true;
1679}
1680
jchen10d9cd7b72017-08-30 15:04:25 +08001681bool ValidateGetProgramInterfaceiv(Context *context,
1682 GLuint program,
1683 GLenum programInterface,
1684 GLenum pname,
1685 GLint *params)
1686{
1687 if (context->getClientVersion() < ES_3_1)
1688 {
1689 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1690 return false;
1691 }
1692
1693 Program *programObject = GetValidProgram(context, program);
1694 if (programObject == nullptr)
1695 {
1696 return false;
1697 }
1698
1699 if (!ValidateProgramInterface(programInterface))
1700 {
1701 context->handleError(InvalidEnum() << "Invalid program interface.");
1702 return false;
1703 }
1704
1705 switch (pname)
1706 {
1707 case GL_ACTIVE_RESOURCES:
1708 case GL_MAX_NAME_LENGTH:
1709 case GL_MAX_NUM_ACTIVE_VARIABLES:
1710 break;
1711
1712 default:
1713 context->handleError(InvalidEnum() << "Unknown property of program interface.");
1714 return false;
1715 }
1716
1717 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1718 {
1719 context->handleError(InvalidOperation()
1720 << "Active atomic counter resources are not assigned name strings.");
1721 return false;
1722 }
1723
1724 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1725 {
1726 switch (programInterface)
1727 {
1728 case GL_ATOMIC_COUNTER_BUFFER:
1729 case GL_SHADER_STORAGE_BLOCK:
1730 case GL_UNIFORM_BLOCK:
1731 break;
1732
1733 default:
1734 context->handleError(
1735 InvalidOperation()
1736 << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
1737 return false;
1738 }
1739 }
1740
1741 return true;
1742}
1743
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001744bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1745 GLuint program,
1746 GLenum programInterface,
1747 GLenum pname,
1748 GLsizei bufSize,
1749 GLsizei *length,
1750 GLint *params)
1751{
1752 UNIMPLEMENTED();
1753 return false;
1754}
1755
Yunchao Hea336b902017-08-02 16:05:21 +08001756static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1757{
1758 if (context->getClientVersion() < ES_3_1)
1759 {
1760 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1761 return false;
1762 }
1763
1764 return ValidateGenOrDelete(context, n);
1765}
1766
1767bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1768{
1769 return ValidateGenOrDeleteES31(context, n);
1770}
1771
1772bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1773{
1774 return ValidateGenOrDeleteES31(context, n);
1775}
1776
1777bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1778{
1779 if (context->getClientVersion() < ES_3_1)
1780 {
1781 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1782 return false;
1783 }
1784
1785 if (!context->isProgramPipelineGenerated(pipeline))
1786 {
1787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
1788 return false;
1789 }
1790
1791 return true;
1792}
1793
1794bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1795{
1796 if (context->getClientVersion() < ES_3_1)
1797 {
1798 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1799 return false;
1800 }
1801
1802 return true;
1803}
1804
Jiajia Qin5451d532017-11-16 17:16:34 +08001805bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1806{
1807 UNIMPLEMENTED();
1808 return false;
1809}
1810
1811bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1812{
1813 UNIMPLEMENTED();
1814 return false;
1815}
1816
1817bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001818 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001819 GLsizei count,
1820 const GLchar *const *strings)
1821{
1822 UNIMPLEMENTED();
1823 return false;
1824}
1825
1826bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1827{
1828 UNIMPLEMENTED();
1829 return false;
1830}
1831
1832bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1833{
1834 UNIMPLEMENTED();
1835 return false;
1836}
1837
1838bool ValidateGetProgramPipelineInfoLog(Context *context,
1839 GLuint pipeline,
1840 GLsizei bufSize,
1841 GLsizei *length,
1842 GLchar *infoLog)
1843{
1844 UNIMPLEMENTED();
1845 return false;
1846}
1847
1848bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1849{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001850 if (context->getClientVersion() < ES_3_1)
1851 {
1852 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1853 return false;
1854 }
1855
1856 if (barriers == GL_ALL_BARRIER_BITS)
1857 {
1858 return true;
1859 }
1860
1861 GLbitfield supported_barrier_bits =
1862 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1863 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1864 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1865 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1866 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1867 if ((barriers & ~supported_barrier_bits) != 0)
1868 {
1869 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1870 return false;
1871 }
1872
1873 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001874}
1875
1876bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1877{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001878 if (context->getClientVersion() < ES_3_1)
1879 {
1880 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1881 return false;
1882 }
1883
1884 if (barriers == GL_ALL_BARRIER_BITS)
1885 {
1886 return true;
1887 }
1888
1889 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1890 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1891 GL_SHADER_STORAGE_BARRIER_BIT |
1892 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1893 if ((barriers & ~supported_barrier_bits) != 0)
1894 {
1895 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1896 return false;
1897 }
1898
1899 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001900}
1901
1902bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001903{
1904 if (context->getClientVersion() < ES_3_1)
1905 {
1906 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1907 return false;
1908 }
1909
1910 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1911 {
1912 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
1913 return false;
1914 }
1915
1916 return true;
1917}
1918
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001919bool ValidateFramebufferTextureEXT(Context *context,
1920 GLenum target,
1921 GLenum attachment,
1922 GLuint texture,
1923 GLint level)
1924{
1925 if (!context->getExtensions().geometryShader)
1926 {
1927 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GeometryShaderExtensionNotEnabled);
1928 return false;
1929 }
1930
1931 if (texture != 0)
1932 {
1933 gl::Texture *tex = context->getTexture(texture);
1934
1935 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
1936 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
1937 // We put this validation before ValidateFramebufferTextureBase because it is an
1938 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
1939 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
1940 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
1941 // existing texture object of type matching textarget.
1942 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
1943 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
1944 // three-dimensional or two-dimensional array texture.
1945 if (tex == nullptr)
1946 {
1947 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureName);
1948 return false;
1949 }
1950
1951 if (!ValidMipLevel(context, tex->getType(), level))
1952 {
1953 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1954 return false;
1955 }
1956 }
1957
1958 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1959 {
1960 return false;
1961 }
1962
1963 return true;
1964}
1965
Olli Etuaho064458a2018-08-30 14:02:02 +03001966// GL_OES_texture_storage_multisample_2d_array
1967bool ValidateTexStorage3DMultisampleOES(Context *context,
1968 TextureType target,
1969 GLsizei samples,
1970 GLint sizedinternalformat,
1971 GLsizei width,
1972 GLsizei height,
1973 GLsizei depth,
1974 GLboolean fixedsamplelocations)
Olli Etuaho89664842018-08-24 14:45:36 +03001975{
Olli Etuaho064458a2018-08-30 14:02:02 +03001976 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03001977 {
1978 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1979 return false;
1980 }
1981
1982 if (target != TextureType::_2DMultisampleArray)
1983 {
Olli Etuaho064458a2018-08-30 14:02:02 +03001984 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TargetMustBeTexture2DMultisampleArrayOES);
Olli Etuahod310a432018-08-24 15:40:23 +03001985 return false;
1986 }
1987
1988 if (width < 1 || height < 1 || depth < 1)
1989 {
1990 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
1991 return false;
1992 }
1993
1994 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
1995 height);
Olli Etuaho89664842018-08-24 14:45:36 +03001996}
1997
Olli Etuaho0ca09752018-09-24 11:00:50 +03001998bool ValidateGetProgramResourceLocationIndexEXT(Context *context,
1999 GLuint program,
2000 GLenum programInterface,
2001 const char *name)
2002{
2003 if (!context->getExtensions().blendFuncExtended)
2004 {
2005 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
2006 return false;
2007 }
2008 if (context->getClientVersion() < ES_3_1)
2009 {
2010 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
2011 return false;
2012 }
2013 if (programInterface != GL_PROGRAM_OUTPUT)
2014 {
2015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ProgramInterfaceMustBeProgramOutput);
2016 return false;
2017 }
2018 Program *programObject = GetValidProgram(context, program);
2019 if (!programObject)
2020 {
2021 return false;
2022 }
2023 if (!programObject->isLinked())
2024 {
2025 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
2026 return false;
2027 }
2028 return true;
2029}
2030
Martin Radev66fb8202016-07-28 11:45:20 +03002031} // namespace gl