blob: b85b7a6c0b9d73bfd68c4a95df8406456bec6bff [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 Madill876429b2017-04-20 15:46:24 -0400413bool ValidateDrawIndirectBase(Context *context, GLenum 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 Madill876429b2017-04-20 15:46:24 -0400471bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800472{
473 const State &state = context->getGLState();
Jamie Madill5b772312018-03-08 20:28:32 -0500474 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
Jiajia Qind9671222016-11-29 16:30:31 +0800475 if (curTransformFeedback && curTransformFeedback->isActive() &&
476 !curTransformFeedback->isPaused())
477 {
478 // An INVALID_OPERATION error is generated if transform feedback is active and not paused.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500479 context->handleError(InvalidOperation() << "transform feedback is active and not paused.");
Jiajia Qind9671222016-11-29 16:30:31 +0800480 return false;
481 }
482
483 if (!ValidateDrawIndirectBase(context, mode, indirect))
484 return false;
485
Jamie Madill5b772312018-03-08 20:28:32 -0500486 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800487 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
488 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
489 // which's size is 4 * sizeof(uint).
490 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
491 if (!checkedSum.IsValid() ||
492 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
493 {
494 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500495 InvalidOperation()
496 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800497 return false;
498 }
499
500 return true;
501}
502
Jamie Madill876429b2017-04-20 15:46:24 -0400503bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800504{
505 if (!ValidateDrawElementsBase(context, type))
506 return false;
507
508 const State &state = context->getGLState();
509 const VertexArray *vao = state.getVertexArray();
Jamie Madill5b772312018-03-08 20:28:32 -0500510 Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
Jiajia Qind9671222016-11-29 16:30:31 +0800511 if (!elementArrayBuffer)
512 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500513 context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800514 return false;
515 }
516
517 if (!ValidateDrawIndirectBase(context, mode, indirect))
518 return false;
519
Jamie Madill5b772312018-03-08 20:28:32 -0500520 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800521 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
522 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
523 // which's size is 5 * sizeof(uint).
524 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
525 if (!checkedSum.IsValid() ||
526 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
527 {
528 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500529 InvalidOperation()
530 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800531 return false;
532 }
533
534 return true;
535}
536
Jiajia Qin5451d532017-11-16 17:16:34 +0800537bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0)
538{
539 return ValidateProgramUniform1iv(context, program, location, 1, &v0);
540}
541
542bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1)
543{
544 GLint xy[2] = {v0, v1};
545 return ValidateProgramUniform2iv(context, program, location, 1, xy);
546}
547
548bool ValidateProgramUniform3i(Context *context,
549 GLuint program,
550 GLint location,
551 GLint v0,
552 GLint v1,
553 GLint v2)
554{
555 GLint xyz[3] = {v0, v1, v2};
556 return ValidateProgramUniform3iv(context, program, location, 1, xyz);
557}
558
559bool ValidateProgramUniform4i(Context *context,
560 GLuint program,
561 GLint location,
562 GLint v0,
563 GLint v1,
564 GLint v2,
565 GLint v3)
566{
567 GLint xyzw[4] = {v0, v1, v2, v3};
568 return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
569}
570
571bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0)
572{
573 return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
574}
575
576bool ValidateProgramUniform2ui(Context *context,
577 GLuint program,
578 GLint location,
579 GLuint v0,
580 GLuint v1)
581{
582 GLuint xy[2] = {v0, v1};
583 return ValidateProgramUniform2uiv(context, program, location, 1, xy);
584}
585
586bool ValidateProgramUniform3ui(Context *context,
587 GLuint program,
588 GLint location,
589 GLuint v0,
590 GLuint v1,
591 GLuint v2)
592{
593 GLuint xyz[3] = {v0, v1, v2};
594 return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
595}
596
597bool ValidateProgramUniform4ui(Context *context,
598 GLuint program,
599 GLint location,
600 GLuint v0,
601 GLuint v1,
602 GLuint v2,
603 GLuint v3)
604{
605 GLuint xyzw[4] = {v0, v1, v2, v3};
606 return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
607}
608
609bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0)
610{
611 return ValidateProgramUniform1fv(context, program, location, 1, &v0);
612}
613
614bool ValidateProgramUniform2f(Context *context,
615 GLuint program,
616 GLint location,
617 GLfloat v0,
618 GLfloat v1)
619{
620 GLfloat xy[2] = {v0, v1};
621 return ValidateProgramUniform2fv(context, program, location, 1, xy);
622}
623
624bool ValidateProgramUniform3f(Context *context,
625 GLuint program,
626 GLint location,
627 GLfloat v0,
628 GLfloat v1,
629 GLfloat v2)
630{
631 GLfloat xyz[3] = {v0, v1, v2};
632 return ValidateProgramUniform3fv(context, program, location, 1, xyz);
633}
634
635bool ValidateProgramUniform4f(Context *context,
636 GLuint program,
637 GLint location,
638 GLfloat v0,
639 GLfloat v1,
640 GLfloat v2,
641 GLfloat v3)
642{
643 GLfloat xyzw[4] = {v0, v1, v2, v3};
644 return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
645}
646
647bool ValidateProgramUniform1iv(Context *context,
648 GLuint program,
649 GLint location,
650 GLsizei count,
651 const GLint *value)
652{
653 // Check for ES31 program uniform entry points
654 if (context->getClientVersion() < Version(3, 1))
655 {
656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
657 return false;
658 }
659
660 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500661 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800662 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
663 ValidateUniform1ivValue(context, uniform->type, count, value);
664}
665
666bool ValidateProgramUniform2iv(Context *context,
667 GLuint program,
668 GLint location,
669 GLsizei count,
670 const GLint *value)
671{
672 return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
673}
674
675bool ValidateProgramUniform3iv(Context *context,
676 GLuint program,
677 GLint location,
678 GLsizei count,
679 const GLint *value)
680{
681 return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
682}
683
684bool ValidateProgramUniform4iv(Context *context,
685 GLuint program,
686 GLint location,
687 GLsizei count,
688 const GLint *value)
689{
690 return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
691}
692
693bool ValidateProgramUniform1uiv(Context *context,
694 GLuint program,
695 GLint location,
696 GLsizei count,
697 const GLuint *value)
698{
699 return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
700}
701
702bool ValidateProgramUniform2uiv(Context *context,
703 GLuint program,
704 GLint location,
705 GLsizei count,
706 const GLuint *value)
707{
708 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
709}
710
711bool ValidateProgramUniform3uiv(Context *context,
712 GLuint program,
713 GLint location,
714 GLsizei count,
715 const GLuint *value)
716{
717 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
718}
719
720bool ValidateProgramUniform4uiv(Context *context,
721 GLuint program,
722 GLint location,
723 GLsizei count,
724 const GLuint *value)
725{
726 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
727}
728
729bool ValidateProgramUniform1fv(Context *context,
730 GLuint program,
731 GLint location,
732 GLsizei count,
733 const GLfloat *value)
734{
735 return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
736}
737
738bool ValidateProgramUniform2fv(Context *context,
739 GLuint program,
740 GLint location,
741 GLsizei count,
742 const GLfloat *value)
743{
744 return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
745}
746
747bool ValidateProgramUniform3fv(Context *context,
748 GLuint program,
749 GLint location,
750 GLsizei count,
751 const GLfloat *value)
752{
753 return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
754}
755
756bool ValidateProgramUniform4fv(Context *context,
757 GLuint program,
758 GLint location,
759 GLsizei count,
760 const GLfloat *value)
761{
762 return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
763}
764
765bool ValidateProgramUniformMatrix2fv(Context *context,
766 GLuint program,
767 GLint location,
768 GLsizei count,
769 GLboolean transpose,
770 const GLfloat *value)
771{
772 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
773 transpose);
774}
775
776bool ValidateProgramUniformMatrix3fv(Context *context,
777 GLuint program,
778 GLint location,
779 GLsizei count,
780 GLboolean transpose,
781 const GLfloat *value)
782{
783 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
784 transpose);
785}
786
787bool ValidateProgramUniformMatrix4fv(Context *context,
788 GLuint program,
789 GLint location,
790 GLsizei count,
791 GLboolean transpose,
792 const GLfloat *value)
793{
794 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
795 transpose);
796}
797
798bool ValidateProgramUniformMatrix2x3fv(Context *context,
799 GLuint program,
800 GLint location,
801 GLsizei count,
802 GLboolean transpose,
803 const GLfloat *value)
804{
805 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
806 transpose);
807}
808
809bool ValidateProgramUniformMatrix3x2fv(Context *context,
810 GLuint program,
811 GLint location,
812 GLsizei count,
813 GLboolean transpose,
814 const GLfloat *value)
815{
816 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
817 transpose);
818}
819
820bool ValidateProgramUniformMatrix2x4fv(Context *context,
821 GLuint program,
822 GLint location,
823 GLsizei count,
824 GLboolean transpose,
825 const GLfloat *value)
826{
827 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
828 transpose);
829}
830
831bool ValidateProgramUniformMatrix4x2fv(Context *context,
832 GLuint program,
833 GLint location,
834 GLsizei count,
835 GLboolean transpose,
836 const GLfloat *value)
837{
838 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
839 transpose);
840}
841
842bool ValidateProgramUniformMatrix3x4fv(Context *context,
843 GLuint program,
844 GLint location,
845 GLsizei count,
846 GLboolean transpose,
847 const GLfloat *value)
848{
849 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
850 transpose);
851}
852
853bool ValidateProgramUniformMatrix4x3fv(Context *context,
854 GLuint program,
855 GLint location,
856 GLsizei count,
857 GLboolean transpose,
858 const GLfloat *value)
859{
860 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
861 transpose);
862}
863
He Yunchao11b038b2016-11-22 21:24:04 +0800864bool ValidateGetTexLevelParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800865 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800866 GLint level,
867 GLenum pname,
868 GLsizei *length)
869{
870 if (context->getClientVersion() < ES_3_1)
871 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700872 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
He Yunchao11b038b2016-11-22 21:24:04 +0800873 return false;
874 }
875
876 if (length)
877 {
878 *length = 0;
879 }
880
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800881 TextureType type = TextureTargetToType(target);
882
883 if (!ValidTexLevelDestinationTarget(context, type))
He Yunchao11b038b2016-11-22 21:24:04 +0800884 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700885 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
He Yunchao11b038b2016-11-22 21:24:04 +0800886 return false;
887 }
888
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800889 if (context->getTargetTexture(type) == nullptr)
He Yunchao11b038b2016-11-22 21:24:04 +0800890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500891 context->handleError(InvalidEnum() << "No texture bound.");
He Yunchao11b038b2016-11-22 21:24:04 +0800892 return false;
893 }
894
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800895 if (!ValidMipLevel(context, type, level))
He Yunchao11b038b2016-11-22 21:24:04 +0800896 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500897 context->handleError(InvalidValue());
He Yunchao11b038b2016-11-22 21:24:04 +0800898 return false;
899 }
900
901 switch (pname)
902 {
903 case GL_TEXTURE_RED_TYPE:
904 case GL_TEXTURE_GREEN_TYPE:
905 case GL_TEXTURE_BLUE_TYPE:
906 case GL_TEXTURE_ALPHA_TYPE:
907 case GL_TEXTURE_DEPTH_TYPE:
908 break;
909 case GL_TEXTURE_RED_SIZE:
910 case GL_TEXTURE_GREEN_SIZE:
911 case GL_TEXTURE_BLUE_SIZE:
912 case GL_TEXTURE_ALPHA_SIZE:
913 case GL_TEXTURE_DEPTH_SIZE:
914 case GL_TEXTURE_STENCIL_SIZE:
915 case GL_TEXTURE_SHARED_SIZE:
916 break;
917 case GL_TEXTURE_INTERNAL_FORMAT:
918 case GL_TEXTURE_WIDTH:
919 case GL_TEXTURE_HEIGHT:
920 case GL_TEXTURE_DEPTH:
921 break;
922 case GL_TEXTURE_SAMPLES:
923 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
924 break;
925 case GL_TEXTURE_COMPRESSED:
926 break;
927 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700928 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
He Yunchao11b038b2016-11-22 21:24:04 +0800929 return false;
930 }
931
932 if (length)
933 {
934 *length = 1;
935 }
936 return true;
937}
938
939bool ValidateGetTexLevelParameterfv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800940 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800941 GLint level,
942 GLenum pname,
943 GLfloat *params)
944{
945 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
946}
947
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700948bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
949 TextureTarget target,
950 GLint level,
951 GLenum pname,
952 GLsizei bufSize,
953 GLsizei *length,
954 GLfloat *params)
955{
956 UNIMPLEMENTED();
957 return false;
958}
959
He Yunchao11b038b2016-11-22 21:24:04 +0800960bool ValidateGetTexLevelParameteriv(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 GLint *params)
965{
966 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
967}
968
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700969bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
970 TextureTarget target,
971 GLint level,
972 GLenum pname,
973 GLsizei bufSize,
974 GLsizei *length,
975 GLint *params)
976{
977 UNIMPLEMENTED();
978 return false;
979}
980
Jiajia Qin5451d532017-11-16 17:16:34 +0800981bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800982 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800983 GLsizei samples,
984 GLint internalFormat,
985 GLsizei width,
986 GLsizei height,
987 GLboolean fixedSampleLocations)
988{
989 if (context->getClientVersion() < ES_3_1)
990 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700991 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800992 return false;
993 }
994
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800995 if (target != TextureType::_2DMultisample)
JiangYizhoubddc46b2016-12-09 09:50:51 +0800996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500997 context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +0800998 return false;
999 }
1000
1001 if (width < 1 || height < 1)
1002 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001003 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001004 return false;
1005 }
1006
1007 const Caps &caps = context->getCaps();
1008 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1009 static_cast<GLuint>(height) > caps.max2DTextureSize)
1010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001011 context
1012 ->handleError(InvalidValue()
1013 << "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001014 return false;
1015 }
1016
1017 if (samples == 0)
1018 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001019 context->handleError(InvalidValue() << "Samples may not be zero.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001020 return false;
1021 }
1022
1023 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
1024 if (!formatCaps.renderable)
1025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001026 context->handleError(InvalidEnum() << "SizedInternalformat must be color-renderable, "
1027 "depth-renderable, or stencil-renderable.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001028 return false;
1029 }
1030
1031 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
1032 // is one of the unsized base internalformats listed in table 8.11.
Geoff Langca271392017-04-05 12:30:00 -04001033 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
1034 if (formatInfo.internalFormat == GL_NONE)
JiangYizhoubddc46b2016-12-09 09:50:51 +08001035 {
1036 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001037 InvalidEnum()
1038 << "Internalformat is one of the unsupported unsized base internalformats.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001039 return false;
1040 }
1041
1042 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
1043 {
1044 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001045 InvalidOperation()
1046 << "Samples must not be greater than maximum supported value for the format.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001047 return false;
1048 }
1049
1050 Texture *texture = context->getTargetTexture(target);
1051 if (!texture || texture->id() == 0)
1052 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001053 context->handleError(InvalidOperation() << "Zero is bound to target.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001054 return false;
1055 }
1056
1057 if (texture->getImmutableFormat())
1058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001059 context->handleError(InvalidOperation() << "The value of TEXTURE_IMMUTABLE_FORMAT for "
1060 "the texture currently bound to target on "
1061 "the active texture unit is true.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001062 return false;
1063 }
1064
1065 return true;
1066}
1067
1068bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
1069{
1070 if (context->getClientVersion() < ES_3_1)
1071 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001072 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001073 return false;
1074 }
1075
1076 if (pname != GL_SAMPLE_POSITION)
1077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001078 context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001079 return false;
1080 }
1081
JiangYizhou5b03f472017-01-09 10:22:53 +08001082 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04001083 GLint samples = framebuffer->getSamples(context);
JiangYizhou5b03f472017-01-09 10:22:53 +08001084
Jamie Madille98b1b52018-03-08 09:47:23 -05001085 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +08001086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001087 context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001088 return false;
1089 }
1090
1091 return true;
1092}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001093
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001094bool ValidateGetMultisamplefvRobustANGLE(Context *context,
1095 GLenum pname,
1096 GLuint index,
1097 GLsizei bufSize,
1098 GLsizei *length,
1099 GLfloat *val)
1100{
1101 UNIMPLEMENTED();
1102 return false;
1103}
1104
Jiajia Qin5451d532017-11-16 17:16:34 +08001105bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001106{
1107 if (context->getClientVersion() < ES_3_1)
1108 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001110 return false;
1111 }
1112
Geoff Lange8afa902017-09-27 15:00:43 -04001113 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001114 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001115 context->handleError(InvalidEnum() << "Invalid framebuffer target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001116 return false;
1117 }
1118
1119 switch (pname)
1120 {
1121 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1122 {
1123 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1124 if (param < 0 || param > maxWidth)
1125 {
1126 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001127 InvalidValue()
1128 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001129 return false;
1130 }
1131 break;
1132 }
1133 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1134 {
1135 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1136 if (param < 0 || param > maxHeight)
1137 {
1138 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001139 InvalidValue()
1140 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001141 return false;
1142 }
1143 break;
1144 }
1145 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1146 {
1147 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1148 if (param < 0 || param > maxSamples)
1149 {
1150 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001151 InvalidValue()
1152 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001153 return false;
1154 }
1155 break;
1156 }
1157 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1158 {
1159 break;
1160 }
1161 default:
1162 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001163 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001164 return false;
1165 }
1166 }
1167
1168 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1169 ASSERT(framebuffer);
1170 if (framebuffer->id() == 0)
1171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001172 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001173 return false;
1174 }
1175 return true;
1176}
1177
Jiajia Qin5451d532017-11-16 17:16:34 +08001178bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001179{
1180 if (context->getClientVersion() < ES_3_1)
1181 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001182 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001183 return false;
1184 }
1185
Geoff Lange8afa902017-09-27 15:00:43 -04001186 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001187 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001188 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001189 return false;
1190 }
1191
1192 switch (pname)
1193 {
1194 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1195 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1196 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1197 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1198 break;
1199 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001201 return false;
1202 }
1203
1204 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1205 ASSERT(framebuffer);
1206
1207 if (framebuffer->id() == 0)
1208 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001209 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001210 return false;
1211 }
1212 return true;
1213}
1214
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001215bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1216 GLenum target,
1217 GLenum pname,
1218 GLsizei bufSize,
1219 GLsizei *length,
1220 GLint *params)
1221{
1222 UNIMPLEMENTED();
1223 return false;
1224}
1225
jchen1015015f72017-03-16 13:54:21 +08001226bool ValidateGetProgramResourceIndex(Context *context,
1227 GLuint program,
1228 GLenum programInterface,
1229 const GLchar *name)
1230{
1231 if (context->getClientVersion() < ES_3_1)
1232 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001233 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen1015015f72017-03-16 13:54:21 +08001234 return false;
1235 }
1236
1237 Program *programObject = GetValidProgram(context, program);
1238 if (programObject == nullptr)
1239 {
1240 return false;
1241 }
1242
1243 if (!ValidateNamedProgramInterface(programInterface))
1244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001245 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1246 << std::uppercase << programInterface);
jchen1015015f72017-03-16 13:54:21 +08001247 return false;
1248 }
Shao80957d92017-02-20 21:25:59 +08001249
1250 return true;
1251}
1252
Jamie Madill5b772312018-03-08 20:28:32 -05001253bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001254 GLuint bindingIndex,
1255 GLuint buffer,
1256 GLintptr offset,
1257 GLsizei stride)
1258{
1259 if (context->getClientVersion() < ES_3_1)
1260 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001261 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001262 return false;
1263 }
1264
1265 if (!context->isBufferGenerated(buffer))
1266 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001267 context->handleError(InvalidOperation() << "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001268 return false;
1269 }
1270
1271 const Caps &caps = context->getCaps();
1272 if (bindingIndex >= caps.maxVertexAttribBindings)
1273 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001274 context->handleError(InvalidValue()
1275 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001276 return false;
1277 }
1278
1279 if (offset < 0)
1280 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001281 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001282 return false;
1283 }
1284
1285 if (stride < 0 || stride > caps.maxVertexAttribStride)
1286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001287 context->handleError(InvalidValue()
1288 << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001289 return false;
1290 }
1291
1292 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1293 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1294 if (context->getGLState().getVertexArrayId() == 0)
1295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001296 context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001297 return false;
1298 }
1299
1300 return true;
1301}
1302
Jamie Madill5b772312018-03-08 20:28:32 -05001303bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001304{
1305 if (context->getClientVersion() < ES_3_1)
1306 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001307 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001308 return false;
1309 }
1310
1311 const Caps &caps = context->getCaps();
1312 if (bindingIndex >= caps.maxVertexAttribBindings)
1313 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001314 context->handleError(InvalidValue()
1315 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001316 return false;
1317 }
1318
1319 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1320 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1321 if (context->getGLState().getVertexArrayId() == 0)
1322 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001323 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001324 return false;
1325 }
1326
1327 return true;
1328}
1329
Jamie Madill5b772312018-03-08 20:28:32 -05001330bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001331 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001332 GLint size,
1333 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001334 GLboolean normalized,
1335 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001336{
Jiajia Qin5451d532017-11-16 17:16:34 +08001337 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1338 false);
1339}
Shao80957d92017-02-20 21:25:59 +08001340
Jamie Madill5b772312018-03-08 20:28:32 -05001341bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001342 GLuint attribindex,
1343 GLint size,
1344 GLenum type,
1345 GLuint relativeoffset)
1346{
1347 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001348}
1349
Jamie Madill5b772312018-03-08 20:28:32 -05001350bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001351{
1352 if (context->getClientVersion() < ES_3_1)
1353 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001355 return false;
1356 }
1357
1358 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1359 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1360 if (context->getGLState().getVertexArrayId() == 0)
1361 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001362 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001363 return false;
1364 }
1365
1366 const Caps &caps = context->getCaps();
1367 if (attribIndex >= caps.maxVertexAttributes)
1368 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001369 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001370 return false;
1371 }
1372
1373 if (bindingIndex >= caps.maxVertexAttribBindings)
1374 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001375 context->handleError(InvalidValue()
1376 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001377 return false;
1378 }
1379
jchen1015015f72017-03-16 13:54:21 +08001380 return true;
1381}
1382
jchen10fd7c3b52017-03-21 15:36:03 +08001383bool ValidateGetProgramResourceName(Context *context,
1384 GLuint program,
1385 GLenum programInterface,
1386 GLuint index,
1387 GLsizei bufSize,
1388 GLsizei *length,
1389 GLchar *name)
1390{
1391 if (context->getClientVersion() < ES_3_1)
1392 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001394 return false;
1395 }
1396
1397 Program *programObject = GetValidProgram(context, program);
1398 if (programObject == nullptr)
1399 {
1400 return false;
1401 }
1402
1403 if (!ValidateNamedProgramInterface(programInterface))
1404 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001405 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1406 << std::uppercase << programInterface);
jchen10fd7c3b52017-03-21 15:36:03 +08001407 return false;
1408 }
1409
1410 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1411 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001412 context->handleError(InvalidValue() << "Invalid index: " << index);
jchen10fd7c3b52017-03-21 15:36:03 +08001413 return false;
1414 }
1415
1416 if (bufSize < 0)
1417 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001418 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001419 return false;
1420 }
1421
1422 return true;
1423}
1424
Xinghua Cao2b396592017-03-29 15:36:04 +08001425bool ValidateDispatchCompute(Context *context,
1426 GLuint numGroupsX,
1427 GLuint numGroupsY,
1428 GLuint numGroupsZ)
1429{
1430 if (context->getClientVersion() < ES_3_1)
1431 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001433 return false;
1434 }
1435
1436 const State &state = context->getGLState();
1437 Program *program = state.getProgram();
1438
Jiawei Shao385b3e02018-03-21 09:43:28 +08001439 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001440 {
Qin Jiajia62fcf622017-11-30 16:16:12 +08001441 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001442 return false;
1443 }
1444
1445 const Caps &caps = context->getCaps();
1446 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1447 {
1448 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001449 InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
1450 << caps.maxComputeWorkGroupCount[0]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001451 return false;
1452 }
1453 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1454 {
1455 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001456 InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]="
1457 << caps.maxComputeWorkGroupCount[1]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001458 return false;
1459 }
1460 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1461 {
1462 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001463 InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
1464 << caps.maxComputeWorkGroupCount[2]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001465 return false;
1466 }
1467
1468 return true;
1469}
1470
Jiajia Qin5451d532017-11-16 17:16:34 +08001471bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1472{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001473 if (context->getClientVersion() < ES_3_1)
1474 {
1475 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1476 return false;
1477 }
1478
1479 const State &state = context->getGLState();
1480 Program *program = state.getProgram();
1481
Jiawei Shao385b3e02018-03-21 09:43:28 +08001482 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001483 {
1484 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
1485 return false;
1486 }
1487
Qin Jiajia62fcf622017-11-30 16:16:12 +08001488 if (indirect < 0)
1489 {
1490 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
1491 return false;
1492 }
1493
1494 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1495 {
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001496 ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
1497 return false;
1498 }
1499
Jamie Madill5b772312018-03-08 20:28:32 -05001500 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001501 if (!dispatchIndirectBuffer)
1502 {
1503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001504 return false;
1505 }
1506
1507 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1508 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1509 if (!checkedSum.IsValid() ||
1510 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1511 {
1512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
1513 return false;
1514 }
1515
1516 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001517}
1518
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001519bool ValidateBindImageTexture(Context *context,
1520 GLuint unit,
1521 GLuint texture,
1522 GLint level,
1523 GLboolean layered,
1524 GLint layer,
1525 GLenum access,
1526 GLenum format)
1527{
1528 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1529 if (unit >= maxImageUnits)
1530 {
1531 context->handleError(InvalidValue()
1532 << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = "
1533 << maxImageUnits);
1534 return false;
1535 }
1536
1537 if (level < 0)
1538 {
1539 context->handleError(InvalidValue() << "level is negative.");
1540 return false;
1541 }
1542
1543 if (layer < 0)
1544 {
1545 context->handleError(InvalidValue() << "layer is negative.");
1546 return false;
1547 }
1548
1549 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1550 {
1551 context->handleError(InvalidEnum() << "access is not one of the supported tokens.");
1552 return false;
1553 }
1554
1555 switch (format)
1556 {
1557 case GL_RGBA32F:
1558 case GL_RGBA16F:
1559 case GL_R32F:
1560 case GL_RGBA32UI:
1561 case GL_RGBA16UI:
1562 case GL_RGBA8UI:
1563 case GL_R32UI:
1564 case GL_RGBA32I:
1565 case GL_RGBA16I:
1566 case GL_RGBA8I:
1567 case GL_R32I:
1568 case GL_RGBA8:
1569 case GL_RGBA8_SNORM:
1570 break;
1571 default:
1572 context->handleError(InvalidValue()
1573 << "format is not one of supported image unit formats.");
1574 return false;
1575 }
1576
1577 if (texture != 0)
1578 {
1579 Texture *tex = context->getTexture(texture);
1580
1581 if (tex == nullptr)
1582 {
1583 context->handleError(InvalidValue()
1584 << "texture is not the name of an existing texture object.");
1585 return false;
1586 }
1587
1588 if (!tex->getImmutableFormat())
1589 {
1590 context->handleError(InvalidOperation()
1591 << "texture is not the name of an immutable texture object.");
1592 return false;
1593 }
1594 }
1595
1596 return true;
1597}
jchen10191381f2017-04-11 13:59:04 +08001598
1599bool ValidateGetProgramResourceLocation(Context *context,
1600 GLuint program,
1601 GLenum programInterface,
1602 const GLchar *name)
1603{
1604 if (context->getClientVersion() < ES_3_1)
1605 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001606 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10191381f2017-04-11 13:59:04 +08001607 return false;
1608 }
1609
1610 Program *programObject = GetValidProgram(context, program);
1611 if (programObject == nullptr)
1612 {
1613 return false;
1614 }
1615
1616 if (!programObject->isLinked())
1617 {
1618 context->handleError(InvalidOperation() << "Program is not successfully linked.");
1619 return false;
1620 }
1621
1622 if (!ValidateLocationProgramInterface(programInterface))
1623 {
1624 context->handleError(InvalidEnum() << "Invalid program interface.");
1625 return false;
1626 }
1627 return true;
1628}
1629
jchen10880683b2017-04-12 16:21:55 +08001630bool ValidateGetProgramResourceiv(Context *context,
1631 GLuint program,
1632 GLenum programInterface,
1633 GLuint index,
1634 GLsizei propCount,
1635 const GLenum *props,
1636 GLsizei bufSize,
1637 GLsizei *length,
1638 GLint *params)
1639{
1640 if (context->getClientVersion() < ES_3_1)
1641 {
jchen10d9cd7b72017-08-30 15:04:25 +08001642 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10880683b2017-04-12 16:21:55 +08001643 return false;
1644 }
1645
1646 Program *programObject = GetValidProgram(context, program);
1647 if (programObject == nullptr)
1648 {
1649 return false;
1650 }
1651 if (!ValidateProgramInterface(programInterface))
1652 {
1653 context->handleError(InvalidEnum() << "Invalid program interface.");
1654 return false;
1655 }
1656 if (propCount <= 0)
1657 {
1658 context->handleError(InvalidValue() << "Invalid propCount.");
1659 return false;
1660 }
1661 if (bufSize < 0)
1662 {
1663 context->handleError(InvalidValue() << "Invalid bufSize.");
1664 return false;
1665 }
1666 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1667 {
1668 context->handleError(InvalidValue() << "Invalid index: " << index);
1669 return false;
1670 }
1671 for (GLsizei i = 0; i < propCount; i++)
1672 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001673 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001674 {
1675 context->handleError(InvalidEnum() << "Invalid prop.");
1676 return false;
1677 }
1678 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1679 {
1680 context->handleError(InvalidOperation() << "Not an allowed prop for interface");
1681 return false;
1682 }
1683 }
1684 return true;
1685}
1686
jchen10d9cd7b72017-08-30 15:04:25 +08001687bool ValidateGetProgramInterfaceiv(Context *context,
1688 GLuint program,
1689 GLenum programInterface,
1690 GLenum pname,
1691 GLint *params)
1692{
1693 if (context->getClientVersion() < ES_3_1)
1694 {
1695 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1696 return false;
1697 }
1698
1699 Program *programObject = GetValidProgram(context, program);
1700 if (programObject == nullptr)
1701 {
1702 return false;
1703 }
1704
1705 if (!ValidateProgramInterface(programInterface))
1706 {
1707 context->handleError(InvalidEnum() << "Invalid program interface.");
1708 return false;
1709 }
1710
1711 switch (pname)
1712 {
1713 case GL_ACTIVE_RESOURCES:
1714 case GL_MAX_NAME_LENGTH:
1715 case GL_MAX_NUM_ACTIVE_VARIABLES:
1716 break;
1717
1718 default:
1719 context->handleError(InvalidEnum() << "Unknown property of program interface.");
1720 return false;
1721 }
1722
1723 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1724 {
1725 context->handleError(InvalidOperation()
1726 << "Active atomic counter resources are not assigned name strings.");
1727 return false;
1728 }
1729
1730 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1731 {
1732 switch (programInterface)
1733 {
1734 case GL_ATOMIC_COUNTER_BUFFER:
1735 case GL_SHADER_STORAGE_BLOCK:
1736 case GL_UNIFORM_BLOCK:
1737 break;
1738
1739 default:
1740 context->handleError(
1741 InvalidOperation()
1742 << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
1743 return false;
1744 }
1745 }
1746
1747 return true;
1748}
1749
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001750bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1751 GLuint program,
1752 GLenum programInterface,
1753 GLenum pname,
1754 GLsizei bufSize,
1755 GLsizei *length,
1756 GLint *params)
1757{
1758 UNIMPLEMENTED();
1759 return false;
1760}
1761
Yunchao Hea336b902017-08-02 16:05:21 +08001762static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1763{
1764 if (context->getClientVersion() < ES_3_1)
1765 {
1766 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1767 return false;
1768 }
1769
1770 return ValidateGenOrDelete(context, n);
1771}
1772
1773bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1774{
1775 return ValidateGenOrDeleteES31(context, n);
1776}
1777
1778bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1779{
1780 return ValidateGenOrDeleteES31(context, n);
1781}
1782
1783bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1784{
1785 if (context->getClientVersion() < ES_3_1)
1786 {
1787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1788 return false;
1789 }
1790
1791 if (!context->isProgramPipelineGenerated(pipeline))
1792 {
1793 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
1794 return false;
1795 }
1796
1797 return true;
1798}
1799
1800bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1801{
1802 if (context->getClientVersion() < ES_3_1)
1803 {
1804 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1805 return false;
1806 }
1807
1808 return true;
1809}
1810
Jiajia Qin5451d532017-11-16 17:16:34 +08001811bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1812{
1813 UNIMPLEMENTED();
1814 return false;
1815}
1816
1817bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1818{
1819 UNIMPLEMENTED();
1820 return false;
1821}
1822
1823bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001824 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001825 GLsizei count,
1826 const GLchar *const *strings)
1827{
1828 UNIMPLEMENTED();
1829 return false;
1830}
1831
1832bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1833{
1834 UNIMPLEMENTED();
1835 return false;
1836}
1837
1838bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1839{
1840 UNIMPLEMENTED();
1841 return false;
1842}
1843
1844bool ValidateGetProgramPipelineInfoLog(Context *context,
1845 GLuint pipeline,
1846 GLsizei bufSize,
1847 GLsizei *length,
1848 GLchar *infoLog)
1849{
1850 UNIMPLEMENTED();
1851 return false;
1852}
1853
1854bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1855{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001856 if (context->getClientVersion() < ES_3_1)
1857 {
1858 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1859 return false;
1860 }
1861
1862 if (barriers == GL_ALL_BARRIER_BITS)
1863 {
1864 return true;
1865 }
1866
1867 GLbitfield supported_barrier_bits =
1868 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1869 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1870 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1871 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1872 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1873 if ((barriers & ~supported_barrier_bits) != 0)
1874 {
1875 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1876 return false;
1877 }
1878
1879 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001880}
1881
1882bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1883{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001884 if (context->getClientVersion() < ES_3_1)
1885 {
1886 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1887 return false;
1888 }
1889
1890 if (barriers == GL_ALL_BARRIER_BITS)
1891 {
1892 return true;
1893 }
1894
1895 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1896 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1897 GL_SHADER_STORAGE_BARRIER_BIT |
1898 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1899 if ((barriers & ~supported_barrier_bits) != 0)
1900 {
1901 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1902 return false;
1903 }
1904
1905 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001906}
1907
1908bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001909{
1910 if (context->getClientVersion() < ES_3_1)
1911 {
1912 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1913 return false;
1914 }
1915
1916 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1917 {
1918 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
1919 return false;
1920 }
1921
1922 return true;
1923}
1924
Martin Radev66fb8202016-07-28 11:45:20 +03001925} // namespace gl