blob: 4ec51b2b5aaf3d85cec3616ae833f65b848e47df [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;
Geoff Lang79b91402018-10-04 15:11:30 -0400957 case GL_MEMORY_SIZE_ANGLE:
958 if (!context->getExtensions().memorySize)
959 {
960 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
961 return false;
962 }
963 break;
964
He Yunchao11b038b2016-11-22 21:24:04 +0800965 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700966 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
He Yunchao11b038b2016-11-22 21:24:04 +0800967 return false;
968 }
969
970 if (length)
971 {
972 *length = 1;
973 }
974 return true;
975}
976
977bool ValidateGetTexLevelParameterfv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800978 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800979 GLint level,
980 GLenum pname,
981 GLfloat *params)
982{
983 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
984}
985
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700986bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
987 TextureTarget target,
988 GLint level,
989 GLenum pname,
990 GLsizei bufSize,
991 GLsizei *length,
992 GLfloat *params)
993{
994 UNIMPLEMENTED();
995 return false;
996}
997
He Yunchao11b038b2016-11-22 21:24:04 +0800998bool ValidateGetTexLevelParameteriv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800999 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +08001000 GLint level,
1001 GLenum pname,
1002 GLint *params)
1003{
1004 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
1005}
1006
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001007bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
1008 TextureTarget target,
1009 GLint level,
1010 GLenum pname,
1011 GLsizei bufSize,
1012 GLsizei *length,
1013 GLint *params)
1014{
1015 UNIMPLEMENTED();
1016 return false;
1017}
1018
Jiajia Qin5451d532017-11-16 17:16:34 +08001019bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001020 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +08001021 GLsizei samples,
1022 GLint internalFormat,
1023 GLsizei width,
1024 GLsizei height,
1025 GLboolean fixedSampleLocations)
1026{
1027 if (context->getClientVersion() < ES_3_1)
1028 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001029 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001030 return false;
1031 }
1032
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001033 if (target != TextureType::_2DMultisample)
JiangYizhoubddc46b2016-12-09 09:50:51 +08001034 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001035 context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001036 return false;
1037 }
1038
1039 if (width < 1 || height < 1)
1040 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001041 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001042 return false;
1043 }
1044
Olli Etuahod310a432018-08-24 15:40:23 +03001045 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001046}
1047
1048bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
1049{
1050 if (context->getClientVersion() < ES_3_1)
1051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001052 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001053 return false;
1054 }
1055
1056 if (pname != GL_SAMPLE_POSITION)
1057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001058 context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001059 return false;
1060 }
1061
JiangYizhou5b03f472017-01-09 10:22:53 +08001062 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04001063 GLint samples = framebuffer->getSamples(context);
JiangYizhou5b03f472017-01-09 10:22:53 +08001064
Jamie Madille98b1b52018-03-08 09:47:23 -05001065 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +08001066 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001067 context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001068 return false;
1069 }
1070
1071 return true;
1072}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001073
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001074bool ValidateGetMultisamplefvRobustANGLE(Context *context,
1075 GLenum pname,
1076 GLuint index,
1077 GLsizei bufSize,
1078 GLsizei *length,
1079 GLfloat *val)
1080{
1081 UNIMPLEMENTED();
1082 return false;
1083}
1084
Jiajia Qin5451d532017-11-16 17:16:34 +08001085bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001086{
1087 if (context->getClientVersion() < ES_3_1)
1088 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001089 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001090 return false;
1091 }
1092
Geoff Lange8afa902017-09-27 15:00:43 -04001093 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001095 context->handleError(InvalidEnum() << "Invalid framebuffer target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001096 return false;
1097 }
1098
1099 switch (pname)
1100 {
1101 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1102 {
1103 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1104 if (param < 0 || param > maxWidth)
1105 {
1106 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001107 InvalidValue()
1108 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001109 return false;
1110 }
1111 break;
1112 }
1113 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1114 {
1115 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1116 if (param < 0 || param > maxHeight)
1117 {
1118 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001119 InvalidValue()
1120 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001121 return false;
1122 }
1123 break;
1124 }
1125 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1126 {
1127 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1128 if (param < 0 || param > maxSamples)
1129 {
1130 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001131 InvalidValue()
1132 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001133 return false;
1134 }
1135 break;
1136 }
1137 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1138 {
1139 break;
1140 }
Jiawei Shaob1e91382018-05-17 14:33:55 +08001141 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1142 {
1143 if (!context->getExtensions().geometryShader)
1144 {
1145 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1146 return false;
1147 }
1148 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1149 if (param < 0 || param > maxLayers)
1150 {
1151 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferLayer);
1152 return false;
1153 }
1154 break;
1155 }
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001156 default:
1157 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001158 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001159 return false;
1160 }
1161 }
1162
1163 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1164 ASSERT(framebuffer);
1165 if (framebuffer->id() == 0)
1166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001167 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001168 return false;
1169 }
1170 return true;
1171}
1172
Jiajia Qin5451d532017-11-16 17:16:34 +08001173bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001174{
1175 if (context->getClientVersion() < ES_3_1)
1176 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001178 return false;
1179 }
1180
Geoff Lange8afa902017-09-27 15:00:43 -04001181 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001182 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001183 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001184 return false;
1185 }
1186
1187 switch (pname)
1188 {
1189 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1190 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1191 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1192 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1193 break;
Jiawei Shaob1e91382018-05-17 14:33:55 +08001194 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1195 if (!context->getExtensions().geometryShader)
1196 {
1197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1198 return false;
1199 }
1200 break;
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001201 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001202 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001203 return false;
1204 }
1205
1206 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1207 ASSERT(framebuffer);
1208
1209 if (framebuffer->id() == 0)
1210 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001211 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001212 return false;
1213 }
1214 return true;
1215}
1216
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001217bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1218 GLenum target,
1219 GLenum pname,
1220 GLsizei bufSize,
1221 GLsizei *length,
1222 GLint *params)
1223{
1224 UNIMPLEMENTED();
1225 return false;
1226}
1227
jchen1015015f72017-03-16 13:54:21 +08001228bool ValidateGetProgramResourceIndex(Context *context,
1229 GLuint program,
1230 GLenum programInterface,
1231 const GLchar *name)
1232{
1233 if (context->getClientVersion() < ES_3_1)
1234 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001235 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen1015015f72017-03-16 13:54:21 +08001236 return false;
1237 }
1238
1239 Program *programObject = GetValidProgram(context, program);
1240 if (programObject == nullptr)
1241 {
1242 return false;
1243 }
1244
1245 if (!ValidateNamedProgramInterface(programInterface))
1246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001247 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1248 << std::uppercase << programInterface);
jchen1015015f72017-03-16 13:54:21 +08001249 return false;
1250 }
Shao80957d92017-02-20 21:25:59 +08001251
1252 return true;
1253}
1254
Jamie Madill5b772312018-03-08 20:28:32 -05001255bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001256 GLuint bindingIndex,
1257 GLuint buffer,
1258 GLintptr offset,
1259 GLsizei stride)
1260{
1261 if (context->getClientVersion() < ES_3_1)
1262 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001263 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001264 return false;
1265 }
1266
1267 if (!context->isBufferGenerated(buffer))
1268 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001269 context->handleError(InvalidOperation() << "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001270 return false;
1271 }
1272
1273 const Caps &caps = context->getCaps();
1274 if (bindingIndex >= caps.maxVertexAttribBindings)
1275 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001276 context->handleError(InvalidValue()
1277 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001278 return false;
1279 }
1280
1281 if (offset < 0)
1282 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001283 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001284 return false;
1285 }
1286
1287 if (stride < 0 || stride > caps.maxVertexAttribStride)
1288 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001289 context->handleError(InvalidValue()
1290 << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001291 return false;
1292 }
1293
1294 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1295 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1296 if (context->getGLState().getVertexArrayId() == 0)
1297 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001298 context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001299 return false;
1300 }
1301
1302 return true;
1303}
1304
Jamie Madill5b772312018-03-08 20:28:32 -05001305bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001306{
1307 if (context->getClientVersion() < ES_3_1)
1308 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001310 return false;
1311 }
1312
1313 const Caps &caps = context->getCaps();
1314 if (bindingIndex >= caps.maxVertexAttribBindings)
1315 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001316 context->handleError(InvalidValue()
1317 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001318 return false;
1319 }
1320
1321 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1322 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1323 if (context->getGLState().getVertexArrayId() == 0)
1324 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001325 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001326 return false;
1327 }
1328
1329 return true;
1330}
1331
Jamie Madill5b772312018-03-08 20:28:32 -05001332bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001333 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001334 GLint size,
1335 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001336 GLboolean normalized,
1337 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001338{
Jiajia Qin5451d532017-11-16 17:16:34 +08001339 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1340 false);
1341}
Shao80957d92017-02-20 21:25:59 +08001342
Jamie Madill5b772312018-03-08 20:28:32 -05001343bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001344 GLuint attribindex,
1345 GLint size,
1346 GLenum type,
1347 GLuint relativeoffset)
1348{
1349 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001350}
1351
Jamie Madill5b772312018-03-08 20:28:32 -05001352bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001353{
1354 if (context->getClientVersion() < ES_3_1)
1355 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001357 return false;
1358 }
1359
1360 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1361 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1362 if (context->getGLState().getVertexArrayId() == 0)
1363 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001364 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001365 return false;
1366 }
1367
1368 const Caps &caps = context->getCaps();
1369 if (attribIndex >= caps.maxVertexAttributes)
1370 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001371 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001372 return false;
1373 }
1374
1375 if (bindingIndex >= caps.maxVertexAttribBindings)
1376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001377 context->handleError(InvalidValue()
1378 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001379 return false;
1380 }
1381
jchen1015015f72017-03-16 13:54:21 +08001382 return true;
1383}
1384
jchen10fd7c3b52017-03-21 15:36:03 +08001385bool ValidateGetProgramResourceName(Context *context,
1386 GLuint program,
1387 GLenum programInterface,
1388 GLuint index,
1389 GLsizei bufSize,
1390 GLsizei *length,
1391 GLchar *name)
1392{
1393 if (context->getClientVersion() < ES_3_1)
1394 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001396 return false;
1397 }
1398
1399 Program *programObject = GetValidProgram(context, program);
1400 if (programObject == nullptr)
1401 {
1402 return false;
1403 }
1404
1405 if (!ValidateNamedProgramInterface(programInterface))
1406 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001407 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1408 << std::uppercase << programInterface);
jchen10fd7c3b52017-03-21 15:36:03 +08001409 return false;
1410 }
1411
1412 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1413 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001414 context->handleError(InvalidValue() << "Invalid index: " << index);
jchen10fd7c3b52017-03-21 15:36:03 +08001415 return false;
1416 }
1417
1418 if (bufSize < 0)
1419 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001420 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001421 return false;
1422 }
1423
1424 return true;
1425}
1426
Xinghua Cao2b396592017-03-29 15:36:04 +08001427bool ValidateDispatchCompute(Context *context,
1428 GLuint numGroupsX,
1429 GLuint numGroupsY,
1430 GLuint numGroupsZ)
1431{
1432 if (context->getClientVersion() < ES_3_1)
1433 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001434 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001435 return false;
1436 }
1437
1438 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001439 Program *program = state.getLinkedProgram(context);
Xinghua Cao2b396592017-03-29 15:36:04 +08001440
Jiawei Shao385b3e02018-03-21 09:43:28 +08001441 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001442 {
Qin Jiajia62fcf622017-11-30 16:16:12 +08001443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001444 return false;
1445 }
1446
1447 const Caps &caps = context->getCaps();
1448 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1449 {
1450 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001451 InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
1452 << caps.maxComputeWorkGroupCount[0]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001453 return false;
1454 }
1455 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1456 {
1457 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001458 InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]="
1459 << caps.maxComputeWorkGroupCount[1]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001460 return false;
1461 }
1462 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1463 {
1464 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001465 InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
1466 << caps.maxComputeWorkGroupCount[2]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001467 return false;
1468 }
1469
1470 return true;
1471}
1472
Jiajia Qin5451d532017-11-16 17:16:34 +08001473bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1474{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001475 if (context->getClientVersion() < ES_3_1)
1476 {
1477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1478 return false;
1479 }
1480
1481 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001482 Program *program = state.getLinkedProgram(context);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001483
Jiawei Shao385b3e02018-03-21 09:43:28 +08001484 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001485 {
1486 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
1487 return false;
1488 }
1489
Qin Jiajia62fcf622017-11-30 16:16:12 +08001490 if (indirect < 0)
1491 {
1492 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
1493 return false;
1494 }
1495
1496 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1497 {
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001498 ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
1499 return false;
1500 }
1501
Jamie Madill5b772312018-03-08 20:28:32 -05001502 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001503 if (!dispatchIndirectBuffer)
1504 {
1505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001506 return false;
1507 }
1508
1509 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1510 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1511 if (!checkedSum.IsValid() ||
1512 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1513 {
1514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
1515 return false;
1516 }
1517
1518 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001519}
1520
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001521bool ValidateBindImageTexture(Context *context,
1522 GLuint unit,
1523 GLuint texture,
1524 GLint level,
1525 GLboolean layered,
1526 GLint layer,
1527 GLenum access,
1528 GLenum format)
1529{
1530 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1531 if (unit >= maxImageUnits)
1532 {
1533 context->handleError(InvalidValue()
1534 << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = "
1535 << maxImageUnits);
1536 return false;
1537 }
1538
1539 if (level < 0)
1540 {
1541 context->handleError(InvalidValue() << "level is negative.");
1542 return false;
1543 }
1544
1545 if (layer < 0)
1546 {
1547 context->handleError(InvalidValue() << "layer is negative.");
1548 return false;
1549 }
1550
1551 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1552 {
1553 context->handleError(InvalidEnum() << "access is not one of the supported tokens.");
1554 return false;
1555 }
1556
1557 switch (format)
1558 {
1559 case GL_RGBA32F:
1560 case GL_RGBA16F:
1561 case GL_R32F:
1562 case GL_RGBA32UI:
1563 case GL_RGBA16UI:
1564 case GL_RGBA8UI:
1565 case GL_R32UI:
1566 case GL_RGBA32I:
1567 case GL_RGBA16I:
1568 case GL_RGBA8I:
1569 case GL_R32I:
1570 case GL_RGBA8:
1571 case GL_RGBA8_SNORM:
1572 break;
1573 default:
1574 context->handleError(InvalidValue()
1575 << "format is not one of supported image unit formats.");
1576 return false;
1577 }
1578
1579 if (texture != 0)
1580 {
1581 Texture *tex = context->getTexture(texture);
1582
1583 if (tex == nullptr)
1584 {
1585 context->handleError(InvalidValue()
1586 << "texture is not the name of an existing texture object.");
1587 return false;
1588 }
1589
1590 if (!tex->getImmutableFormat())
1591 {
1592 context->handleError(InvalidOperation()
1593 << "texture is not the name of an immutable texture object.");
1594 return false;
1595 }
1596 }
1597
1598 return true;
1599}
jchen10191381f2017-04-11 13:59:04 +08001600
1601bool ValidateGetProgramResourceLocation(Context *context,
1602 GLuint program,
1603 GLenum programInterface,
1604 const GLchar *name)
1605{
1606 if (context->getClientVersion() < ES_3_1)
1607 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001608 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10191381f2017-04-11 13:59:04 +08001609 return false;
1610 }
1611
1612 Program *programObject = GetValidProgram(context, program);
1613 if (programObject == nullptr)
1614 {
1615 return false;
1616 }
1617
1618 if (!programObject->isLinked())
1619 {
1620 context->handleError(InvalidOperation() << "Program is not successfully linked.");
1621 return false;
1622 }
1623
1624 if (!ValidateLocationProgramInterface(programInterface))
1625 {
1626 context->handleError(InvalidEnum() << "Invalid program interface.");
1627 return false;
1628 }
1629 return true;
1630}
1631
jchen10880683b2017-04-12 16:21:55 +08001632bool ValidateGetProgramResourceiv(Context *context,
1633 GLuint program,
1634 GLenum programInterface,
1635 GLuint index,
1636 GLsizei propCount,
1637 const GLenum *props,
1638 GLsizei bufSize,
1639 GLsizei *length,
1640 GLint *params)
1641{
1642 if (context->getClientVersion() < ES_3_1)
1643 {
jchen10d9cd7b72017-08-30 15:04:25 +08001644 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10880683b2017-04-12 16:21:55 +08001645 return false;
1646 }
1647
1648 Program *programObject = GetValidProgram(context, program);
1649 if (programObject == nullptr)
1650 {
1651 return false;
1652 }
1653 if (!ValidateProgramInterface(programInterface))
1654 {
1655 context->handleError(InvalidEnum() << "Invalid program interface.");
1656 return false;
1657 }
1658 if (propCount <= 0)
1659 {
1660 context->handleError(InvalidValue() << "Invalid propCount.");
1661 return false;
1662 }
1663 if (bufSize < 0)
1664 {
1665 context->handleError(InvalidValue() << "Invalid bufSize.");
1666 return false;
1667 }
1668 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1669 {
1670 context->handleError(InvalidValue() << "Invalid index: " << index);
1671 return false;
1672 }
1673 for (GLsizei i = 0; i < propCount; i++)
1674 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001675 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001676 {
1677 context->handleError(InvalidEnum() << "Invalid prop.");
1678 return false;
1679 }
1680 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1681 {
1682 context->handleError(InvalidOperation() << "Not an allowed prop for interface");
1683 return false;
1684 }
1685 }
1686 return true;
1687}
1688
jchen10d9cd7b72017-08-30 15:04:25 +08001689bool ValidateGetProgramInterfaceiv(Context *context,
1690 GLuint program,
1691 GLenum programInterface,
1692 GLenum pname,
1693 GLint *params)
1694{
1695 if (context->getClientVersion() < ES_3_1)
1696 {
1697 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1698 return false;
1699 }
1700
1701 Program *programObject = GetValidProgram(context, program);
1702 if (programObject == nullptr)
1703 {
1704 return false;
1705 }
1706
1707 if (!ValidateProgramInterface(programInterface))
1708 {
1709 context->handleError(InvalidEnum() << "Invalid program interface.");
1710 return false;
1711 }
1712
1713 switch (pname)
1714 {
1715 case GL_ACTIVE_RESOURCES:
1716 case GL_MAX_NAME_LENGTH:
1717 case GL_MAX_NUM_ACTIVE_VARIABLES:
1718 break;
1719
1720 default:
1721 context->handleError(InvalidEnum() << "Unknown property of program interface.");
1722 return false;
1723 }
1724
1725 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1726 {
1727 context->handleError(InvalidOperation()
1728 << "Active atomic counter resources are not assigned name strings.");
1729 return false;
1730 }
1731
1732 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1733 {
1734 switch (programInterface)
1735 {
1736 case GL_ATOMIC_COUNTER_BUFFER:
1737 case GL_SHADER_STORAGE_BLOCK:
1738 case GL_UNIFORM_BLOCK:
1739 break;
1740
1741 default:
1742 context->handleError(
1743 InvalidOperation()
1744 << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
1745 return false;
1746 }
1747 }
1748
1749 return true;
1750}
1751
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001752bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1753 GLuint program,
1754 GLenum programInterface,
1755 GLenum pname,
1756 GLsizei bufSize,
1757 GLsizei *length,
1758 GLint *params)
1759{
1760 UNIMPLEMENTED();
1761 return false;
1762}
1763
Yunchao Hea336b902017-08-02 16:05:21 +08001764static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1765{
1766 if (context->getClientVersion() < ES_3_1)
1767 {
1768 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1769 return false;
1770 }
1771
1772 return ValidateGenOrDelete(context, n);
1773}
1774
1775bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1776{
1777 return ValidateGenOrDeleteES31(context, n);
1778}
1779
1780bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1781{
1782 return ValidateGenOrDeleteES31(context, n);
1783}
1784
1785bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1786{
1787 if (context->getClientVersion() < ES_3_1)
1788 {
1789 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1790 return false;
1791 }
1792
1793 if (!context->isProgramPipelineGenerated(pipeline))
1794 {
1795 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
1796 return false;
1797 }
1798
1799 return true;
1800}
1801
1802bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1803{
1804 if (context->getClientVersion() < ES_3_1)
1805 {
1806 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1807 return false;
1808 }
1809
1810 return true;
1811}
1812
Jiajia Qin5451d532017-11-16 17:16:34 +08001813bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1814{
1815 UNIMPLEMENTED();
1816 return false;
1817}
1818
1819bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1820{
1821 UNIMPLEMENTED();
1822 return false;
1823}
1824
1825bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001826 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001827 GLsizei count,
1828 const GLchar *const *strings)
1829{
1830 UNIMPLEMENTED();
1831 return false;
1832}
1833
1834bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1835{
1836 UNIMPLEMENTED();
1837 return false;
1838}
1839
1840bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1841{
1842 UNIMPLEMENTED();
1843 return false;
1844}
1845
1846bool ValidateGetProgramPipelineInfoLog(Context *context,
1847 GLuint pipeline,
1848 GLsizei bufSize,
1849 GLsizei *length,
1850 GLchar *infoLog)
1851{
1852 UNIMPLEMENTED();
1853 return false;
1854}
1855
1856bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1857{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001858 if (context->getClientVersion() < ES_3_1)
1859 {
1860 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1861 return false;
1862 }
1863
1864 if (barriers == GL_ALL_BARRIER_BITS)
1865 {
1866 return true;
1867 }
1868
1869 GLbitfield supported_barrier_bits =
1870 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1871 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1872 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1873 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1874 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1875 if ((barriers & ~supported_barrier_bits) != 0)
1876 {
1877 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1878 return false;
1879 }
1880
1881 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001882}
1883
1884bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1885{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001886 if (context->getClientVersion() < ES_3_1)
1887 {
1888 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1889 return false;
1890 }
1891
1892 if (barriers == GL_ALL_BARRIER_BITS)
1893 {
1894 return true;
1895 }
1896
1897 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1898 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1899 GL_SHADER_STORAGE_BARRIER_BIT |
1900 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1901 if ((barriers & ~supported_barrier_bits) != 0)
1902 {
1903 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1904 return false;
1905 }
1906
1907 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001908}
1909
1910bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001911{
1912 if (context->getClientVersion() < ES_3_1)
1913 {
1914 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1915 return false;
1916 }
1917
1918 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1919 {
1920 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
1921 return false;
1922 }
1923
1924 return true;
1925}
1926
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001927bool ValidateFramebufferTextureEXT(Context *context,
1928 GLenum target,
1929 GLenum attachment,
1930 GLuint texture,
1931 GLint level)
1932{
1933 if (!context->getExtensions().geometryShader)
1934 {
1935 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GeometryShaderExtensionNotEnabled);
1936 return false;
1937 }
1938
1939 if (texture != 0)
1940 {
1941 gl::Texture *tex = context->getTexture(texture);
1942
1943 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
1944 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
1945 // We put this validation before ValidateFramebufferTextureBase because it is an
1946 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
1947 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
1948 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
1949 // existing texture object of type matching textarget.
1950 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
1951 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
1952 // three-dimensional or two-dimensional array texture.
1953 if (tex == nullptr)
1954 {
1955 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureName);
1956 return false;
1957 }
1958
1959 if (!ValidMipLevel(context, tex->getType(), level))
1960 {
1961 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1962 return false;
1963 }
1964 }
1965
1966 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1967 {
1968 return false;
1969 }
1970
1971 return true;
1972}
1973
Olli Etuaho064458a2018-08-30 14:02:02 +03001974// GL_OES_texture_storage_multisample_2d_array
1975bool ValidateTexStorage3DMultisampleOES(Context *context,
1976 TextureType target,
1977 GLsizei samples,
1978 GLint sizedinternalformat,
1979 GLsizei width,
1980 GLsizei height,
1981 GLsizei depth,
1982 GLboolean fixedsamplelocations)
Olli Etuaho89664842018-08-24 14:45:36 +03001983{
Olli Etuaho064458a2018-08-30 14:02:02 +03001984 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03001985 {
1986 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1987 return false;
1988 }
1989
1990 if (target != TextureType::_2DMultisampleArray)
1991 {
Olli Etuaho064458a2018-08-30 14:02:02 +03001992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TargetMustBeTexture2DMultisampleArrayOES);
Olli Etuahod310a432018-08-24 15:40:23 +03001993 return false;
1994 }
1995
1996 if (width < 1 || height < 1 || depth < 1)
1997 {
1998 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
1999 return false;
2000 }
2001
2002 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
2003 height);
Olli Etuaho89664842018-08-24 14:45:36 +03002004}
2005
Olli Etuaho0ca09752018-09-24 11:00:50 +03002006bool ValidateGetProgramResourceLocationIndexEXT(Context *context,
2007 GLuint program,
2008 GLenum programInterface,
2009 const char *name)
2010{
2011 if (!context->getExtensions().blendFuncExtended)
2012 {
2013 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
2014 return false;
2015 }
2016 if (context->getClientVersion() < ES_3_1)
2017 {
2018 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
2019 return false;
2020 }
2021 if (programInterface != GL_PROGRAM_OUTPUT)
2022 {
2023 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ProgramInterfaceMustBeProgramOutput);
2024 return false;
2025 }
2026 Program *programObject = GetValidProgram(context, program);
2027 if (!programObject)
2028 {
2029 return false;
2030 }
2031 if (!programObject->isLinked())
2032 {
2033 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
2034 return false;
2035 }
2036 return true;
2037}
2038
Martin Radev66fb8202016-07-28 11:45:20 +03002039} // namespace gl