blob: 518f967f38b2795b245b616f437e33bf0cc86e1c [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
jchen10880683b2017-04-12 16:21:55 +0800104 default:
105 return false;
106 }
107}
108
109// GLES 3.10 spec: Page 82 -- Table 7.2
110bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
111{
112 switch (prop)
113 {
114 case GL_ACTIVE_VARIABLES:
115 case GL_BUFFER_BINDING:
116 case GL_NUM_ACTIVE_VARIABLES:
117 {
118 switch (programInterface)
119 {
120 case GL_ATOMIC_COUNTER_BUFFER:
121 case GL_SHADER_STORAGE_BLOCK:
122 case GL_UNIFORM_BLOCK:
123 return true;
124 default:
125 return false;
126 }
127 }
128
129 case GL_ARRAY_SIZE:
130 {
131 switch (programInterface)
132 {
133 case GL_BUFFER_VARIABLE:
134 case GL_PROGRAM_INPUT:
135 case GL_PROGRAM_OUTPUT:
136 case GL_TRANSFORM_FEEDBACK_VARYING:
137 case GL_UNIFORM:
138 return true;
139 default:
140 return false;
141 }
142 }
143
144 case GL_ARRAY_STRIDE:
145 case GL_BLOCK_INDEX:
146 case GL_IS_ROW_MAJOR:
147 case GL_MATRIX_STRIDE:
148 {
149 switch (programInterface)
150 {
151 case GL_BUFFER_VARIABLE:
152 case GL_UNIFORM:
153 return true;
154 default:
155 return false;
156 }
157 }
158
159 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
160 {
161 if (programInterface == GL_UNIFORM)
162 {
163 return true;
164 }
165 return false;
166 }
167
168 case GL_BUFFER_DATA_SIZE:
169 {
170 switch (programInterface)
171 {
172 case GL_ATOMIC_COUNTER_BUFFER:
173 case GL_SHADER_STORAGE_BLOCK:
174 case GL_UNIFORM_BLOCK:
175 return true;
176 default:
177 return false;
178 }
179 }
180
181 case GL_LOCATION:
182 {
183 return ValidateLocationProgramInterface(programInterface);
184 }
185
186 case GL_NAME_LENGTH:
187 {
188 return ValidateNamedProgramInterface(programInterface);
189 }
190
191 case GL_OFFSET:
192 {
193 switch (programInterface)
194 {
195 case GL_BUFFER_VARIABLE:
196 case GL_UNIFORM:
197 return true;
198 default:
199 return false;
200 }
201 }
202
203 case GL_REFERENCED_BY_VERTEX_SHADER:
204 case GL_REFERENCED_BY_FRAGMENT_SHADER:
205 case GL_REFERENCED_BY_COMPUTE_SHADER:
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800206 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
jchen10880683b2017-04-12 16:21:55 +0800207 {
208 switch (programInterface)
209 {
210 case GL_ATOMIC_COUNTER_BUFFER:
211 case GL_BUFFER_VARIABLE:
212 case GL_PROGRAM_INPUT:
213 case GL_PROGRAM_OUTPUT:
214 case GL_SHADER_STORAGE_BLOCK:
215 case GL_UNIFORM:
216 case GL_UNIFORM_BLOCK:
217 return true;
218 default:
219 return false;
220 }
221 }
222
223 case GL_TOP_LEVEL_ARRAY_SIZE:
224 case GL_TOP_LEVEL_ARRAY_STRIDE:
225 {
226 if (programInterface == GL_BUFFER_VARIABLE)
227 {
228 return true;
229 }
230 return false;
231 }
232
233 case GL_TYPE:
234 {
235 switch (programInterface)
236 {
237 case GL_BUFFER_VARIABLE:
238 case GL_PROGRAM_INPUT:
239 case GL_PROGRAM_OUTPUT:
240 case GL_TRANSFORM_FEEDBACK_VARYING:
241 case GL_UNIFORM:
242 return true;
243 default:
244 return false;
245 }
246 }
247
248 default:
249 return false;
250 }
251}
252
jchen10fd7c3b52017-03-21 15:36:03 +0800253bool ValidateProgramResourceIndex(const Program *programObject,
254 GLenum programInterface,
255 GLuint index)
256{
257 switch (programInterface)
258 {
259 case GL_PROGRAM_INPUT:
260 return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
261
262 case GL_PROGRAM_OUTPUT:
263 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
264
jchen10fd7c3b52017-03-21 15:36:03 +0800265 case GL_UNIFORM:
jchen10baf5d942017-08-28 20:45:48 +0800266 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
267
Jiajia Qin3a9090f2017-09-27 14:37:04 +0800268 case GL_BUFFER_VARIABLE:
269 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
270
271 case GL_SHADER_STORAGE_BLOCK:
272 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
273
jchen10fd7c3b52017-03-21 15:36:03 +0800274 case GL_UNIFORM_BLOCK:
jchen1058f67be2017-10-27 08:59:27 +0800275 return (index < programObject->getActiveUniformBlockCount());
276
277 case GL_ATOMIC_COUNTER_BUFFER:
278 return (index < programObject->getActiveAtomicCounterBufferCount());
279
jchen10fd7c3b52017-03-21 15:36:03 +0800280 case GL_TRANSFORM_FEEDBACK_VARYING:
jchen10910a3da2017-11-15 09:40:11 +0800281 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
jchen10fd7c3b52017-03-21 15:36:03 +0800282
283 default:
284 UNREACHABLE();
285 return false;
286 }
287}
288
Jamie Madill5b772312018-03-08 20:28:32 -0500289bool ValidateProgramUniform(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800290 GLenum valueType,
291 GLuint program,
292 GLint location,
293 GLsizei count)
294{
295 // Check for ES31 program uniform entry points
296 if (context->getClientVersion() < Version(3, 1))
297 {
298 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
299 return false;
300 }
301
302 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500303 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800304 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
305 ValidateUniformValue(context, valueType, uniform->type);
306}
307
Jamie Madill5b772312018-03-08 20:28:32 -0500308bool ValidateProgramUniformMatrix(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800309 GLenum valueType,
310 GLuint program,
311 GLint location,
312 GLsizei count,
313 GLboolean transpose)
314{
315 // Check for ES31 program uniform entry points
316 if (context->getClientVersion() < Version(3, 1))
317 {
318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
319 return false;
320 }
321
322 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500323 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800324 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
325 ValidateUniformMatrixValue(context, valueType, uniform->type);
326}
327
Jamie Madill5b772312018-03-08 20:28:32 -0500328bool ValidateVertexAttribFormatCommon(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800329 GLuint attribIndex,
330 GLint size,
331 GLenum type,
332 GLuint relativeOffset,
333 GLboolean pureInteger)
334{
335 if (context->getClientVersion() < ES_3_1)
336 {
337 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
338 return false;
339 }
340
341 const Caps &caps = context->getCaps();
342 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
343 {
344 context->handleError(
345 InvalidValue()
346 << "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
347 return false;
348 }
349
350 // [OpenGL ES 3.1] Section 10.3.1 page 243:
351 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
352 if (context->getGLState().getVertexArrayId() == 0)
353 {
354 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
355 return false;
356 }
357
358 return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
359}
360
jchen1015015f72017-03-16 13:54:21 +0800361} // anonymous namespace
362
Martin Radev66fb8202016-07-28 11:45:20 +0300363bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
364{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400365 if (context->getClientVersion() < ES_3_1)
Martin Radev66fb8202016-07-28 11:45:20 +0300366 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Martin Radev66fb8202016-07-28 11:45:20 +0300368 return false;
369 }
370
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400371 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
372 {
373 return false;
374 }
375
376 return true;
377}
378
379bool ValidateGetBooleani_vRobustANGLE(Context *context,
380 GLenum target,
381 GLuint index,
382 GLsizei bufSize,
383 GLsizei *length,
384 GLboolean *data)
385{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400386 if (context->getClientVersion() < ES_3_1)
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400387 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400389 return false;
390 }
391
392 if (!ValidateRobustEntryPoint(context, bufSize))
393 {
394 return false;
395 }
396
Brandon Jonesd1049182018-03-28 10:02:20 -0700397 GLsizei numParams = 0;
398
399 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400400 {
401 return false;
402 }
403
Brandon Jonesd1049182018-03-28 10:02:20 -0700404 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Martin Radev66fb8202016-07-28 11:45:20 +0300405 {
406 return false;
407 }
408
Brandon Jonesd1049182018-03-28 10:02:20 -0700409 SetRobustLengthParam(length, numParams);
Martin Radev66fb8202016-07-28 11:45:20 +0300410 return true;
411}
412
Jamie Madill493f9572018-05-24 19:52:15 -0400413bool ValidateDrawIndirectBase(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800414{
415 if (context->getClientVersion() < ES_3_1)
416 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jiajia Qind9671222016-11-29 16:30:31 +0800418 return false;
419 }
420
421 // Here the third parameter 1 is only to pass the count validation.
422 if (!ValidateDrawBase(context, mode, 1))
423 {
424 return false;
425 }
426
427 const State &state = context->getGLState();
428
429 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
430 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
431 if (!state.getVertexArrayId())
432 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500433 context->handleError(InvalidOperation() << "zero is bound to VERTEX_ARRAY_BINDING");
Jiajia Qind9671222016-11-29 16:30:31 +0800434 return false;
435 }
436
Jamie Madill5b772312018-03-08 20:28:32 -0500437 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800438 if (!drawIndirectBuffer)
439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500440 context->handleError(InvalidOperation() << "zero is bound to DRAW_INDIRECT_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800441 return false;
442 }
443
444 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
445 // machine units, of uint.
446 GLint64 offset = reinterpret_cast<GLint64>(indirect);
447 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
448 {
449 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500450 InvalidValue()
451 << "indirect is not a multiple of the size, in basic machine units, of uint");
Jiajia Qind9671222016-11-29 16:30:31 +0800452 return false;
453 }
454
Martin Radev14a26ae2017-07-24 15:56:29 +0300455 // ANGLE_multiview spec, revision 1:
456 // An INVALID_OPERATION is generated by DrawArraysIndirect and DrawElementsIndirect if the
457 // number of views in the draw framebuffer is greater than 1.
458 const Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
459 ASSERT(drawFramebuffer != nullptr);
460 if (drawFramebuffer->getNumViews() > 1)
461 {
462 context->handleError(
463 InvalidOperation()
464 << "The number of views in the active draw framebuffer is greater than 1.");
465 return false;
466 }
467
Jiajia Qind9671222016-11-29 16:30:31 +0800468 return true;
469}
470
Jamie Madill493f9572018-05-24 19:52:15 -0400471bool ValidateDrawArraysIndirect(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800472{
Jamie Madill493f9572018-05-24 19:52:15 -0400473 const State &state = context->getGLState();
474 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
Jiajia Qind9671222016-11-29 16:30:31 +0800475 if (curTransformFeedback && curTransformFeedback->isActive() &&
476 !curTransformFeedback->isPaused())
477 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800478 // EXT_geometry_shader allows transform feedback to work with all draw commands.
479 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
480 if (context->getExtensions().geometryShader)
481 {
482 if (!ValidateTransformFeedbackPrimitiveMode(
483 context, curTransformFeedback->getPrimitiveMode(), mode))
484 {
485 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
486 return false;
487 }
488 }
489 else
490 {
491 // An INVALID_OPERATION error is generated if transform feedback is active and not
492 // paused.
493 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
494 UnsupportedDrawModeForTransformFeedback);
495 return false;
496 }
Jiajia Qind9671222016-11-29 16:30:31 +0800497 }
498
499 if (!ValidateDrawIndirectBase(context, mode, indirect))
500 return false;
501
Jamie Madill5b772312018-03-08 20:28:32 -0500502 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800503 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
504 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
505 // which's size is 4 * sizeof(uint).
506 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
507 if (!checkedSum.IsValid() ||
508 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
509 {
510 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500511 InvalidOperation()
512 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800513 return false;
514 }
515
516 return true;
517}
518
Jamie Madill493f9572018-05-24 19:52:15 -0400519bool ValidateDrawElementsIndirect(Context *context,
520 PrimitiveMode mode,
521 GLenum type,
522 const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800523{
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800524 if (!ValidateDrawElementsBase(context, mode, type))
525 {
Jiajia Qind9671222016-11-29 16:30:31 +0800526 return false;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800527 }
Jiajia Qind9671222016-11-29 16:30:31 +0800528
Jamie Madill493f9572018-05-24 19:52:15 -0400529 const State &state = context->getGLState();
530 const VertexArray *vao = state.getVertexArray();
531 Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
Jiajia Qind9671222016-11-29 16:30:31 +0800532 if (!elementArrayBuffer)
533 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500534 context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800535 return false;
536 }
537
538 if (!ValidateDrawIndirectBase(context, mode, indirect))
539 return false;
540
Jamie Madill5b772312018-03-08 20:28:32 -0500541 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800542 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
543 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
544 // which's size is 5 * sizeof(uint).
545 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
546 if (!checkedSum.IsValid() ||
547 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
548 {
549 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500550 InvalidOperation()
551 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800552 return false;
553 }
554
555 return true;
556}
557
Jiajia Qin5451d532017-11-16 17:16:34 +0800558bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0)
559{
560 return ValidateProgramUniform1iv(context, program, location, 1, &v0);
561}
562
563bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1)
564{
565 GLint xy[2] = {v0, v1};
566 return ValidateProgramUniform2iv(context, program, location, 1, xy);
567}
568
569bool ValidateProgramUniform3i(Context *context,
570 GLuint program,
571 GLint location,
572 GLint v0,
573 GLint v1,
574 GLint v2)
575{
576 GLint xyz[3] = {v0, v1, v2};
577 return ValidateProgramUniform3iv(context, program, location, 1, xyz);
578}
579
580bool ValidateProgramUniform4i(Context *context,
581 GLuint program,
582 GLint location,
583 GLint v0,
584 GLint v1,
585 GLint v2,
586 GLint v3)
587{
588 GLint xyzw[4] = {v0, v1, v2, v3};
589 return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
590}
591
592bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0)
593{
594 return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
595}
596
597bool ValidateProgramUniform2ui(Context *context,
598 GLuint program,
599 GLint location,
600 GLuint v0,
601 GLuint v1)
602{
603 GLuint xy[2] = {v0, v1};
604 return ValidateProgramUniform2uiv(context, program, location, 1, xy);
605}
606
607bool ValidateProgramUniform3ui(Context *context,
608 GLuint program,
609 GLint location,
610 GLuint v0,
611 GLuint v1,
612 GLuint v2)
613{
614 GLuint xyz[3] = {v0, v1, v2};
615 return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
616}
617
618bool ValidateProgramUniform4ui(Context *context,
619 GLuint program,
620 GLint location,
621 GLuint v0,
622 GLuint v1,
623 GLuint v2,
624 GLuint v3)
625{
626 GLuint xyzw[4] = {v0, v1, v2, v3};
627 return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
628}
629
630bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0)
631{
632 return ValidateProgramUniform1fv(context, program, location, 1, &v0);
633}
634
635bool ValidateProgramUniform2f(Context *context,
636 GLuint program,
637 GLint location,
638 GLfloat v0,
639 GLfloat v1)
640{
641 GLfloat xy[2] = {v0, v1};
642 return ValidateProgramUniform2fv(context, program, location, 1, xy);
643}
644
645bool ValidateProgramUniform3f(Context *context,
646 GLuint program,
647 GLint location,
648 GLfloat v0,
649 GLfloat v1,
650 GLfloat v2)
651{
652 GLfloat xyz[3] = {v0, v1, v2};
653 return ValidateProgramUniform3fv(context, program, location, 1, xyz);
654}
655
656bool ValidateProgramUniform4f(Context *context,
657 GLuint program,
658 GLint location,
659 GLfloat v0,
660 GLfloat v1,
661 GLfloat v2,
662 GLfloat v3)
663{
664 GLfloat xyzw[4] = {v0, v1, v2, v3};
665 return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
666}
667
668bool ValidateProgramUniform1iv(Context *context,
669 GLuint program,
670 GLint location,
671 GLsizei count,
672 const GLint *value)
673{
674 // Check for ES31 program uniform entry points
675 if (context->getClientVersion() < Version(3, 1))
676 {
677 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
678 return false;
679 }
680
681 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500682 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800683 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
684 ValidateUniform1ivValue(context, uniform->type, count, value);
685}
686
687bool ValidateProgramUniform2iv(Context *context,
688 GLuint program,
689 GLint location,
690 GLsizei count,
691 const GLint *value)
692{
693 return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
694}
695
696bool ValidateProgramUniform3iv(Context *context,
697 GLuint program,
698 GLint location,
699 GLsizei count,
700 const GLint *value)
701{
702 return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
703}
704
705bool ValidateProgramUniform4iv(Context *context,
706 GLuint program,
707 GLint location,
708 GLsizei count,
709 const GLint *value)
710{
711 return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
712}
713
714bool ValidateProgramUniform1uiv(Context *context,
715 GLuint program,
716 GLint location,
717 GLsizei count,
718 const GLuint *value)
719{
720 return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
721}
722
723bool ValidateProgramUniform2uiv(Context *context,
724 GLuint program,
725 GLint location,
726 GLsizei count,
727 const GLuint *value)
728{
729 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
730}
731
732bool ValidateProgramUniform3uiv(Context *context,
733 GLuint program,
734 GLint location,
735 GLsizei count,
736 const GLuint *value)
737{
738 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
739}
740
741bool ValidateProgramUniform4uiv(Context *context,
742 GLuint program,
743 GLint location,
744 GLsizei count,
745 const GLuint *value)
746{
747 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
748}
749
750bool ValidateProgramUniform1fv(Context *context,
751 GLuint program,
752 GLint location,
753 GLsizei count,
754 const GLfloat *value)
755{
756 return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
757}
758
759bool ValidateProgramUniform2fv(Context *context,
760 GLuint program,
761 GLint location,
762 GLsizei count,
763 const GLfloat *value)
764{
765 return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
766}
767
768bool ValidateProgramUniform3fv(Context *context,
769 GLuint program,
770 GLint location,
771 GLsizei count,
772 const GLfloat *value)
773{
774 return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
775}
776
777bool ValidateProgramUniform4fv(Context *context,
778 GLuint program,
779 GLint location,
780 GLsizei count,
781 const GLfloat *value)
782{
783 return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
784}
785
786bool ValidateProgramUniformMatrix2fv(Context *context,
787 GLuint program,
788 GLint location,
789 GLsizei count,
790 GLboolean transpose,
791 const GLfloat *value)
792{
793 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
794 transpose);
795}
796
797bool ValidateProgramUniformMatrix3fv(Context *context,
798 GLuint program,
799 GLint location,
800 GLsizei count,
801 GLboolean transpose,
802 const GLfloat *value)
803{
804 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
805 transpose);
806}
807
808bool ValidateProgramUniformMatrix4fv(Context *context,
809 GLuint program,
810 GLint location,
811 GLsizei count,
812 GLboolean transpose,
813 const GLfloat *value)
814{
815 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
816 transpose);
817}
818
819bool ValidateProgramUniformMatrix2x3fv(Context *context,
820 GLuint program,
821 GLint location,
822 GLsizei count,
823 GLboolean transpose,
824 const GLfloat *value)
825{
826 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
827 transpose);
828}
829
830bool ValidateProgramUniformMatrix3x2fv(Context *context,
831 GLuint program,
832 GLint location,
833 GLsizei count,
834 GLboolean transpose,
835 const GLfloat *value)
836{
837 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
838 transpose);
839}
840
841bool ValidateProgramUniformMatrix2x4fv(Context *context,
842 GLuint program,
843 GLint location,
844 GLsizei count,
845 GLboolean transpose,
846 const GLfloat *value)
847{
848 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
849 transpose);
850}
851
852bool ValidateProgramUniformMatrix4x2fv(Context *context,
853 GLuint program,
854 GLint location,
855 GLsizei count,
856 GLboolean transpose,
857 const GLfloat *value)
858{
859 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
860 transpose);
861}
862
863bool ValidateProgramUniformMatrix3x4fv(Context *context,
864 GLuint program,
865 GLint location,
866 GLsizei count,
867 GLboolean transpose,
868 const GLfloat *value)
869{
870 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
871 transpose);
872}
873
874bool ValidateProgramUniformMatrix4x3fv(Context *context,
875 GLuint program,
876 GLint location,
877 GLsizei count,
878 GLboolean transpose,
879 const GLfloat *value)
880{
881 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
882 transpose);
883}
884
He Yunchao11b038b2016-11-22 21:24:04 +0800885bool ValidateGetTexLevelParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800886 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800887 GLint level,
888 GLenum pname,
889 GLsizei *length)
890{
891 if (context->getClientVersion() < ES_3_1)
892 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700893 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
He Yunchao11b038b2016-11-22 21:24:04 +0800894 return false;
895 }
896
897 if (length)
898 {
899 *length = 0;
900 }
901
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800902 TextureType type = TextureTargetToType(target);
903
904 if (!ValidTexLevelDestinationTarget(context, type))
He Yunchao11b038b2016-11-22 21:24:04 +0800905 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700906 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
He Yunchao11b038b2016-11-22 21:24:04 +0800907 return false;
908 }
909
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800910 if (context->getTargetTexture(type) == nullptr)
He Yunchao11b038b2016-11-22 21:24:04 +0800911 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500912 context->handleError(InvalidEnum() << "No texture bound.");
He Yunchao11b038b2016-11-22 21:24:04 +0800913 return false;
914 }
915
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800916 if (!ValidMipLevel(context, type, level))
He Yunchao11b038b2016-11-22 21:24:04 +0800917 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500918 context->handleError(InvalidValue());
He Yunchao11b038b2016-11-22 21:24:04 +0800919 return false;
920 }
921
922 switch (pname)
923 {
924 case GL_TEXTURE_RED_TYPE:
925 case GL_TEXTURE_GREEN_TYPE:
926 case GL_TEXTURE_BLUE_TYPE:
927 case GL_TEXTURE_ALPHA_TYPE:
928 case GL_TEXTURE_DEPTH_TYPE:
929 break;
930 case GL_TEXTURE_RED_SIZE:
931 case GL_TEXTURE_GREEN_SIZE:
932 case GL_TEXTURE_BLUE_SIZE:
933 case GL_TEXTURE_ALPHA_SIZE:
934 case GL_TEXTURE_DEPTH_SIZE:
935 case GL_TEXTURE_STENCIL_SIZE:
936 case GL_TEXTURE_SHARED_SIZE:
937 break;
938 case GL_TEXTURE_INTERNAL_FORMAT:
939 case GL_TEXTURE_WIDTH:
940 case GL_TEXTURE_HEIGHT:
941 case GL_TEXTURE_DEPTH:
942 break;
943 case GL_TEXTURE_SAMPLES:
944 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
945 break;
946 case GL_TEXTURE_COMPRESSED:
947 break;
948 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700949 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
He Yunchao11b038b2016-11-22 21:24:04 +0800950 return false;
951 }
952
953 if (length)
954 {
955 *length = 1;
956 }
957 return true;
958}
959
960bool ValidateGetTexLevelParameterfv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800961 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800962 GLint level,
963 GLenum pname,
964 GLfloat *params)
965{
966 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
967}
968
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700969bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
970 TextureTarget target,
971 GLint level,
972 GLenum pname,
973 GLsizei bufSize,
974 GLsizei *length,
975 GLfloat *params)
976{
977 UNIMPLEMENTED();
978 return false;
979}
980
He Yunchao11b038b2016-11-22 21:24:04 +0800981bool ValidateGetTexLevelParameteriv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800982 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800983 GLint level,
984 GLenum pname,
985 GLint *params)
986{
987 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
988}
989
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700990bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
991 TextureTarget target,
992 GLint level,
993 GLenum pname,
994 GLsizei bufSize,
995 GLsizei *length,
996 GLint *params)
997{
998 UNIMPLEMENTED();
999 return false;
1000}
1001
Jiajia Qin5451d532017-11-16 17:16:34 +08001002bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001003 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +08001004 GLsizei samples,
1005 GLint internalFormat,
1006 GLsizei width,
1007 GLsizei height,
1008 GLboolean fixedSampleLocations)
1009{
1010 if (context->getClientVersion() < ES_3_1)
1011 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001012 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001013 return false;
1014 }
1015
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001016 if (target != TextureType::_2DMultisample)
JiangYizhoubddc46b2016-12-09 09:50:51 +08001017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001018 context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001019 return false;
1020 }
1021
1022 if (width < 1 || height < 1)
1023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001024 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001025 return false;
1026 }
1027
Olli Etuahod310a432018-08-24 15:40:23 +03001028 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001029}
1030
1031bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
1032{
1033 if (context->getClientVersion() < ES_3_1)
1034 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001035 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001036 return false;
1037 }
1038
1039 if (pname != GL_SAMPLE_POSITION)
1040 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001041 context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001042 return false;
1043 }
1044
JiangYizhou5b03f472017-01-09 10:22:53 +08001045 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04001046 GLint samples = framebuffer->getSamples(context);
JiangYizhou5b03f472017-01-09 10:22:53 +08001047
Jamie Madille98b1b52018-03-08 09:47:23 -05001048 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +08001049 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001050 context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001051 return false;
1052 }
1053
1054 return true;
1055}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001056
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001057bool ValidateGetMultisamplefvRobustANGLE(Context *context,
1058 GLenum pname,
1059 GLuint index,
1060 GLsizei bufSize,
1061 GLsizei *length,
1062 GLfloat *val)
1063{
1064 UNIMPLEMENTED();
1065 return false;
1066}
1067
Jiajia Qin5451d532017-11-16 17:16:34 +08001068bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001069{
1070 if (context->getClientVersion() < ES_3_1)
1071 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001072 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001073 return false;
1074 }
1075
Geoff Lange8afa902017-09-27 15:00:43 -04001076 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001078 context->handleError(InvalidEnum() << "Invalid framebuffer target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001079 return false;
1080 }
1081
1082 switch (pname)
1083 {
1084 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1085 {
1086 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1087 if (param < 0 || param > maxWidth)
1088 {
1089 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001090 InvalidValue()
1091 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001092 return false;
1093 }
1094 break;
1095 }
1096 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1097 {
1098 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1099 if (param < 0 || param > maxHeight)
1100 {
1101 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001102 InvalidValue()
1103 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001104 return false;
1105 }
1106 break;
1107 }
1108 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1109 {
1110 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1111 if (param < 0 || param > maxSamples)
1112 {
1113 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001114 InvalidValue()
1115 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001116 return false;
1117 }
1118 break;
1119 }
1120 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1121 {
1122 break;
1123 }
Jiawei Shaob1e91382018-05-17 14:33:55 +08001124 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1125 {
1126 if (!context->getExtensions().geometryShader)
1127 {
1128 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1129 return false;
1130 }
1131 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1132 if (param < 0 || param > maxLayers)
1133 {
1134 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferLayer);
1135 return false;
1136 }
1137 break;
1138 }
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001139 default:
1140 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001141 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001142 return false;
1143 }
1144 }
1145
1146 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1147 ASSERT(framebuffer);
1148 if (framebuffer->id() == 0)
1149 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001150 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001151 return false;
1152 }
1153 return true;
1154}
1155
Jiajia Qin5451d532017-11-16 17:16:34 +08001156bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001157{
1158 if (context->getClientVersion() < ES_3_1)
1159 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001161 return false;
1162 }
1163
Geoff Lange8afa902017-09-27 15:00:43 -04001164 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001165 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001166 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001167 return false;
1168 }
1169
1170 switch (pname)
1171 {
1172 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1173 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1174 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1175 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1176 break;
Jiawei Shaob1e91382018-05-17 14:33:55 +08001177 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1178 if (!context->getExtensions().geometryShader)
1179 {
1180 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
1181 return false;
1182 }
1183 break;
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001184 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001185 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001186 return false;
1187 }
1188
1189 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1190 ASSERT(framebuffer);
1191
1192 if (framebuffer->id() == 0)
1193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001194 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001195 return false;
1196 }
1197 return true;
1198}
1199
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001200bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1201 GLenum target,
1202 GLenum pname,
1203 GLsizei bufSize,
1204 GLsizei *length,
1205 GLint *params)
1206{
1207 UNIMPLEMENTED();
1208 return false;
1209}
1210
jchen1015015f72017-03-16 13:54:21 +08001211bool ValidateGetProgramResourceIndex(Context *context,
1212 GLuint program,
1213 GLenum programInterface,
1214 const GLchar *name)
1215{
1216 if (context->getClientVersion() < ES_3_1)
1217 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001218 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen1015015f72017-03-16 13:54:21 +08001219 return false;
1220 }
1221
1222 Program *programObject = GetValidProgram(context, program);
1223 if (programObject == nullptr)
1224 {
1225 return false;
1226 }
1227
1228 if (!ValidateNamedProgramInterface(programInterface))
1229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001230 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1231 << std::uppercase << programInterface);
jchen1015015f72017-03-16 13:54:21 +08001232 return false;
1233 }
Shao80957d92017-02-20 21:25:59 +08001234
1235 return true;
1236}
1237
Jamie Madill5b772312018-03-08 20:28:32 -05001238bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001239 GLuint bindingIndex,
1240 GLuint buffer,
1241 GLintptr offset,
1242 GLsizei stride)
1243{
1244 if (context->getClientVersion() < ES_3_1)
1245 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001247 return false;
1248 }
1249
1250 if (!context->isBufferGenerated(buffer))
1251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001252 context->handleError(InvalidOperation() << "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001253 return false;
1254 }
1255
1256 const Caps &caps = context->getCaps();
1257 if (bindingIndex >= caps.maxVertexAttribBindings)
1258 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001259 context->handleError(InvalidValue()
1260 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001261 return false;
1262 }
1263
1264 if (offset < 0)
1265 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001266 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001267 return false;
1268 }
1269
1270 if (stride < 0 || stride > caps.maxVertexAttribStride)
1271 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001272 context->handleError(InvalidValue()
1273 << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001274 return false;
1275 }
1276
1277 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1278 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1279 if (context->getGLState().getVertexArrayId() == 0)
1280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001281 context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001282 return false;
1283 }
1284
1285 return true;
1286}
1287
Jamie Madill5b772312018-03-08 20:28:32 -05001288bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001289{
1290 if (context->getClientVersion() < ES_3_1)
1291 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001293 return false;
1294 }
1295
1296 const Caps &caps = context->getCaps();
1297 if (bindingIndex >= caps.maxVertexAttribBindings)
1298 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001299 context->handleError(InvalidValue()
1300 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001301 return false;
1302 }
1303
1304 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1305 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1306 if (context->getGLState().getVertexArrayId() == 0)
1307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001308 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001309 return false;
1310 }
1311
1312 return true;
1313}
1314
Jamie Madill5b772312018-03-08 20:28:32 -05001315bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001316 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001317 GLint size,
1318 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001319 GLboolean normalized,
1320 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001321{
Jiajia Qin5451d532017-11-16 17:16:34 +08001322 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1323 false);
1324}
Shao80957d92017-02-20 21:25:59 +08001325
Jamie Madill5b772312018-03-08 20:28:32 -05001326bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001327 GLuint attribindex,
1328 GLint size,
1329 GLenum type,
1330 GLuint relativeoffset)
1331{
1332 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001333}
1334
Jamie Madill5b772312018-03-08 20:28:32 -05001335bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001336{
1337 if (context->getClientVersion() < ES_3_1)
1338 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001340 return false;
1341 }
1342
1343 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1344 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1345 if (context->getGLState().getVertexArrayId() == 0)
1346 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001347 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001348 return false;
1349 }
1350
1351 const Caps &caps = context->getCaps();
1352 if (attribIndex >= caps.maxVertexAttributes)
1353 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001354 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001355 return false;
1356 }
1357
1358 if (bindingIndex >= caps.maxVertexAttribBindings)
1359 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001360 context->handleError(InvalidValue()
1361 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001362 return false;
1363 }
1364
jchen1015015f72017-03-16 13:54:21 +08001365 return true;
1366}
1367
jchen10fd7c3b52017-03-21 15:36:03 +08001368bool ValidateGetProgramResourceName(Context *context,
1369 GLuint program,
1370 GLenum programInterface,
1371 GLuint index,
1372 GLsizei bufSize,
1373 GLsizei *length,
1374 GLchar *name)
1375{
1376 if (context->getClientVersion() < ES_3_1)
1377 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001379 return false;
1380 }
1381
1382 Program *programObject = GetValidProgram(context, program);
1383 if (programObject == nullptr)
1384 {
1385 return false;
1386 }
1387
1388 if (!ValidateNamedProgramInterface(programInterface))
1389 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001390 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1391 << std::uppercase << programInterface);
jchen10fd7c3b52017-03-21 15:36:03 +08001392 return false;
1393 }
1394
1395 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1396 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001397 context->handleError(InvalidValue() << "Invalid index: " << index);
jchen10fd7c3b52017-03-21 15:36:03 +08001398 return false;
1399 }
1400
1401 if (bufSize < 0)
1402 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001403 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001404 return false;
1405 }
1406
1407 return true;
1408}
1409
Xinghua Cao2b396592017-03-29 15:36:04 +08001410bool ValidateDispatchCompute(Context *context,
1411 GLuint numGroupsX,
1412 GLuint numGroupsY,
1413 GLuint numGroupsZ)
1414{
1415 if (context->getClientVersion() < ES_3_1)
1416 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001418 return false;
1419 }
1420
1421 const State &state = context->getGLState();
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001422 Program *program = state.getLinkedProgram();
Xinghua Cao2b396592017-03-29 15:36:04 +08001423
Jiawei Shao385b3e02018-03-21 09:43:28 +08001424 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001425 {
Qin Jiajia62fcf622017-11-30 16:16:12 +08001426 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001427 return false;
1428 }
1429
1430 const Caps &caps = context->getCaps();
1431 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1432 {
1433 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001434 InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
1435 << caps.maxComputeWorkGroupCount[0]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001436 return false;
1437 }
1438 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1439 {
1440 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]="
1442 << caps.maxComputeWorkGroupCount[1]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001443 return false;
1444 }
1445 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1446 {
1447 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001448 InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
1449 << caps.maxComputeWorkGroupCount[2]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001450 return false;
1451 }
1452
1453 return true;
1454}
1455
Jiajia Qin5451d532017-11-16 17:16:34 +08001456bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1457{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001458 if (context->getClientVersion() < ES_3_1)
1459 {
1460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1461 return false;
1462 }
1463
1464 const State &state = context->getGLState();
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001465 Program *program = state.getLinkedProgram();
Qin Jiajia62fcf622017-11-30 16:16:12 +08001466
Jiawei Shao385b3e02018-03-21 09:43:28 +08001467 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001468 {
1469 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
1470 return false;
1471 }
1472
Qin Jiajia62fcf622017-11-30 16:16:12 +08001473 if (indirect < 0)
1474 {
1475 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
1476 return false;
1477 }
1478
1479 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1480 {
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001481 ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
1482 return false;
1483 }
1484
Jamie Madill5b772312018-03-08 20:28:32 -05001485 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001486 if (!dispatchIndirectBuffer)
1487 {
1488 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001489 return false;
1490 }
1491
1492 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1493 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1494 if (!checkedSum.IsValid() ||
1495 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1496 {
1497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
1498 return false;
1499 }
1500
1501 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001502}
1503
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001504bool ValidateBindImageTexture(Context *context,
1505 GLuint unit,
1506 GLuint texture,
1507 GLint level,
1508 GLboolean layered,
1509 GLint layer,
1510 GLenum access,
1511 GLenum format)
1512{
1513 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1514 if (unit >= maxImageUnits)
1515 {
1516 context->handleError(InvalidValue()
1517 << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = "
1518 << maxImageUnits);
1519 return false;
1520 }
1521
1522 if (level < 0)
1523 {
1524 context->handleError(InvalidValue() << "level is negative.");
1525 return false;
1526 }
1527
1528 if (layer < 0)
1529 {
1530 context->handleError(InvalidValue() << "layer is negative.");
1531 return false;
1532 }
1533
1534 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1535 {
1536 context->handleError(InvalidEnum() << "access is not one of the supported tokens.");
1537 return false;
1538 }
1539
1540 switch (format)
1541 {
1542 case GL_RGBA32F:
1543 case GL_RGBA16F:
1544 case GL_R32F:
1545 case GL_RGBA32UI:
1546 case GL_RGBA16UI:
1547 case GL_RGBA8UI:
1548 case GL_R32UI:
1549 case GL_RGBA32I:
1550 case GL_RGBA16I:
1551 case GL_RGBA8I:
1552 case GL_R32I:
1553 case GL_RGBA8:
1554 case GL_RGBA8_SNORM:
1555 break;
1556 default:
1557 context->handleError(InvalidValue()
1558 << "format is not one of supported image unit formats.");
1559 return false;
1560 }
1561
1562 if (texture != 0)
1563 {
1564 Texture *tex = context->getTexture(texture);
1565
1566 if (tex == nullptr)
1567 {
1568 context->handleError(InvalidValue()
1569 << "texture is not the name of an existing texture object.");
1570 return false;
1571 }
1572
1573 if (!tex->getImmutableFormat())
1574 {
1575 context->handleError(InvalidOperation()
1576 << "texture is not the name of an immutable texture object.");
1577 return false;
1578 }
1579 }
1580
1581 return true;
1582}
jchen10191381f2017-04-11 13:59:04 +08001583
1584bool ValidateGetProgramResourceLocation(Context *context,
1585 GLuint program,
1586 GLenum programInterface,
1587 const GLchar *name)
1588{
1589 if (context->getClientVersion() < ES_3_1)
1590 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10191381f2017-04-11 13:59:04 +08001592 return false;
1593 }
1594
1595 Program *programObject = GetValidProgram(context, program);
1596 if (programObject == nullptr)
1597 {
1598 return false;
1599 }
1600
1601 if (!programObject->isLinked())
1602 {
1603 context->handleError(InvalidOperation() << "Program is not successfully linked.");
1604 return false;
1605 }
1606
1607 if (!ValidateLocationProgramInterface(programInterface))
1608 {
1609 context->handleError(InvalidEnum() << "Invalid program interface.");
1610 return false;
1611 }
1612 return true;
1613}
1614
jchen10880683b2017-04-12 16:21:55 +08001615bool ValidateGetProgramResourceiv(Context *context,
1616 GLuint program,
1617 GLenum programInterface,
1618 GLuint index,
1619 GLsizei propCount,
1620 const GLenum *props,
1621 GLsizei bufSize,
1622 GLsizei *length,
1623 GLint *params)
1624{
1625 if (context->getClientVersion() < ES_3_1)
1626 {
jchen10d9cd7b72017-08-30 15:04:25 +08001627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10880683b2017-04-12 16:21:55 +08001628 return false;
1629 }
1630
1631 Program *programObject = GetValidProgram(context, program);
1632 if (programObject == nullptr)
1633 {
1634 return false;
1635 }
1636 if (!ValidateProgramInterface(programInterface))
1637 {
1638 context->handleError(InvalidEnum() << "Invalid program interface.");
1639 return false;
1640 }
1641 if (propCount <= 0)
1642 {
1643 context->handleError(InvalidValue() << "Invalid propCount.");
1644 return false;
1645 }
1646 if (bufSize < 0)
1647 {
1648 context->handleError(InvalidValue() << "Invalid bufSize.");
1649 return false;
1650 }
1651 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1652 {
1653 context->handleError(InvalidValue() << "Invalid index: " << index);
1654 return false;
1655 }
1656 for (GLsizei i = 0; i < propCount; i++)
1657 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001658 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001659 {
1660 context->handleError(InvalidEnum() << "Invalid prop.");
1661 return false;
1662 }
1663 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1664 {
1665 context->handleError(InvalidOperation() << "Not an allowed prop for interface");
1666 return false;
1667 }
1668 }
1669 return true;
1670}
1671
jchen10d9cd7b72017-08-30 15:04:25 +08001672bool ValidateGetProgramInterfaceiv(Context *context,
1673 GLuint program,
1674 GLenum programInterface,
1675 GLenum pname,
1676 GLint *params)
1677{
1678 if (context->getClientVersion() < ES_3_1)
1679 {
1680 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1681 return false;
1682 }
1683
1684 Program *programObject = GetValidProgram(context, program);
1685 if (programObject == nullptr)
1686 {
1687 return false;
1688 }
1689
1690 if (!ValidateProgramInterface(programInterface))
1691 {
1692 context->handleError(InvalidEnum() << "Invalid program interface.");
1693 return false;
1694 }
1695
1696 switch (pname)
1697 {
1698 case GL_ACTIVE_RESOURCES:
1699 case GL_MAX_NAME_LENGTH:
1700 case GL_MAX_NUM_ACTIVE_VARIABLES:
1701 break;
1702
1703 default:
1704 context->handleError(InvalidEnum() << "Unknown property of program interface.");
1705 return false;
1706 }
1707
1708 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1709 {
1710 context->handleError(InvalidOperation()
1711 << "Active atomic counter resources are not assigned name strings.");
1712 return false;
1713 }
1714
1715 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1716 {
1717 switch (programInterface)
1718 {
1719 case GL_ATOMIC_COUNTER_BUFFER:
1720 case GL_SHADER_STORAGE_BLOCK:
1721 case GL_UNIFORM_BLOCK:
1722 break;
1723
1724 default:
1725 context->handleError(
1726 InvalidOperation()
1727 << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
1728 return false;
1729 }
1730 }
1731
1732 return true;
1733}
1734
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001735bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1736 GLuint program,
1737 GLenum programInterface,
1738 GLenum pname,
1739 GLsizei bufSize,
1740 GLsizei *length,
1741 GLint *params)
1742{
1743 UNIMPLEMENTED();
1744 return false;
1745}
1746
Yunchao Hea336b902017-08-02 16:05:21 +08001747static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1748{
1749 if (context->getClientVersion() < ES_3_1)
1750 {
1751 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1752 return false;
1753 }
1754
1755 return ValidateGenOrDelete(context, n);
1756}
1757
1758bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1759{
1760 return ValidateGenOrDeleteES31(context, n);
1761}
1762
1763bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1764{
1765 return ValidateGenOrDeleteES31(context, n);
1766}
1767
1768bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1769{
1770 if (context->getClientVersion() < ES_3_1)
1771 {
1772 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1773 return false;
1774 }
1775
1776 if (!context->isProgramPipelineGenerated(pipeline))
1777 {
1778 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
1779 return false;
1780 }
1781
1782 return true;
1783}
1784
1785bool ValidateIsProgramPipeline(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 return true;
1794}
1795
Jiajia Qin5451d532017-11-16 17:16:34 +08001796bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1797{
1798 UNIMPLEMENTED();
1799 return false;
1800}
1801
1802bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1803{
1804 UNIMPLEMENTED();
1805 return false;
1806}
1807
1808bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001809 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001810 GLsizei count,
1811 const GLchar *const *strings)
1812{
1813 UNIMPLEMENTED();
1814 return false;
1815}
1816
1817bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1818{
1819 UNIMPLEMENTED();
1820 return false;
1821}
1822
1823bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1824{
1825 UNIMPLEMENTED();
1826 return false;
1827}
1828
1829bool ValidateGetProgramPipelineInfoLog(Context *context,
1830 GLuint pipeline,
1831 GLsizei bufSize,
1832 GLsizei *length,
1833 GLchar *infoLog)
1834{
1835 UNIMPLEMENTED();
1836 return false;
1837}
1838
1839bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1840{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001841 if (context->getClientVersion() < ES_3_1)
1842 {
1843 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1844 return false;
1845 }
1846
1847 if (barriers == GL_ALL_BARRIER_BITS)
1848 {
1849 return true;
1850 }
1851
1852 GLbitfield supported_barrier_bits =
1853 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1854 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1855 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1856 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1857 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1858 if ((barriers & ~supported_barrier_bits) != 0)
1859 {
1860 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1861 return false;
1862 }
1863
1864 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001865}
1866
1867bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1868{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001869 if (context->getClientVersion() < ES_3_1)
1870 {
1871 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1872 return false;
1873 }
1874
1875 if (barriers == GL_ALL_BARRIER_BITS)
1876 {
1877 return true;
1878 }
1879
1880 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1881 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1882 GL_SHADER_STORAGE_BARRIER_BIT |
1883 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1884 if ((barriers & ~supported_barrier_bits) != 0)
1885 {
1886 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1887 return false;
1888 }
1889
1890 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001891}
1892
1893bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001894{
1895 if (context->getClientVersion() < ES_3_1)
1896 {
1897 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1898 return false;
1899 }
1900
1901 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1902 {
1903 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
1904 return false;
1905 }
1906
1907 return true;
1908}
1909
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001910bool ValidateFramebufferTextureEXT(Context *context,
1911 GLenum target,
1912 GLenum attachment,
1913 GLuint texture,
1914 GLint level)
1915{
1916 if (!context->getExtensions().geometryShader)
1917 {
1918 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GeometryShaderExtensionNotEnabled);
1919 return false;
1920 }
1921
1922 if (texture != 0)
1923 {
1924 gl::Texture *tex = context->getTexture(texture);
1925
1926 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
1927 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
1928 // We put this validation before ValidateFramebufferTextureBase because it is an
1929 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
1930 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
1931 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
1932 // existing texture object of type matching textarget.
1933 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
1934 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
1935 // three-dimensional or two-dimensional array texture.
1936 if (tex == nullptr)
1937 {
1938 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidTextureName);
1939 return false;
1940 }
1941
1942 if (!ValidMipLevel(context, tex->getType(), level))
1943 {
1944 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1945 return false;
1946 }
1947 }
1948
1949 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1950 {
1951 return false;
1952 }
1953
1954 return true;
1955}
1956
Olli Etuaho064458a2018-08-30 14:02:02 +03001957// GL_OES_texture_storage_multisample_2d_array
1958bool ValidateTexStorage3DMultisampleOES(Context *context,
1959 TextureType target,
1960 GLsizei samples,
1961 GLint sizedinternalformat,
1962 GLsizei width,
1963 GLsizei height,
1964 GLsizei depth,
1965 GLboolean fixedsamplelocations)
Olli Etuaho89664842018-08-24 14:45:36 +03001966{
Olli Etuaho064458a2018-08-30 14:02:02 +03001967 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03001968 {
1969 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1970 return false;
1971 }
1972
1973 if (target != TextureType::_2DMultisampleArray)
1974 {
Olli Etuaho064458a2018-08-30 14:02:02 +03001975 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TargetMustBeTexture2DMultisampleArrayOES);
Olli Etuahod310a432018-08-24 15:40:23 +03001976 return false;
1977 }
1978
1979 if (width < 1 || height < 1 || depth < 1)
1980 {
1981 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
1982 return false;
1983 }
1984
1985 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
1986 height);
Olli Etuaho89664842018-08-24 14:45:36 +03001987}
1988
Martin Radev66fb8202016-07-28 11:45:20 +03001989} // namespace gl