blob: 097e4638e04ee5bd1e6e2caf047c8699174b2d9e [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
65bool ValidateProgramResourceProperty(GLenum prop)
66{
67 switch (prop)
68 {
69 case GL_ACTIVE_VARIABLES:
70 case GL_BUFFER_BINDING:
71 case GL_NUM_ACTIVE_VARIABLES:
72
73 case GL_ARRAY_SIZE:
74
75 case GL_ARRAY_STRIDE:
76 case GL_BLOCK_INDEX:
77 case GL_IS_ROW_MAJOR:
78 case GL_MATRIX_STRIDE:
79
80 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
81
82 case GL_BUFFER_DATA_SIZE:
83
84 case GL_LOCATION:
85
86 case GL_NAME_LENGTH:
87
88 case GL_OFFSET:
89
90 case GL_REFERENCED_BY_VERTEX_SHADER:
91 case GL_REFERENCED_BY_FRAGMENT_SHADER:
92 case GL_REFERENCED_BY_COMPUTE_SHADER:
93
94 case GL_TOP_LEVEL_ARRAY_SIZE:
95 case GL_TOP_LEVEL_ARRAY_STRIDE:
96
97 case GL_TYPE:
98 return true;
99
100 default:
101 return false;
102 }
103}
104
105// GLES 3.10 spec: Page 82 -- Table 7.2
106bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
107{
108 switch (prop)
109 {
110 case GL_ACTIVE_VARIABLES:
111 case GL_BUFFER_BINDING:
112 case GL_NUM_ACTIVE_VARIABLES:
113 {
114 switch (programInterface)
115 {
116 case GL_ATOMIC_COUNTER_BUFFER:
117 case GL_SHADER_STORAGE_BLOCK:
118 case GL_UNIFORM_BLOCK:
119 return true;
120 default:
121 return false;
122 }
123 }
124
125 case GL_ARRAY_SIZE:
126 {
127 switch (programInterface)
128 {
129 case GL_BUFFER_VARIABLE:
130 case GL_PROGRAM_INPUT:
131 case GL_PROGRAM_OUTPUT:
132 case GL_TRANSFORM_FEEDBACK_VARYING:
133 case GL_UNIFORM:
134 return true;
135 default:
136 return false;
137 }
138 }
139
140 case GL_ARRAY_STRIDE:
141 case GL_BLOCK_INDEX:
142 case GL_IS_ROW_MAJOR:
143 case GL_MATRIX_STRIDE:
144 {
145 switch (programInterface)
146 {
147 case GL_BUFFER_VARIABLE:
148 case GL_UNIFORM:
149 return true;
150 default:
151 return false;
152 }
153 }
154
155 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
156 {
157 if (programInterface == GL_UNIFORM)
158 {
159 return true;
160 }
161 return false;
162 }
163
164 case GL_BUFFER_DATA_SIZE:
165 {
166 switch (programInterface)
167 {
168 case GL_ATOMIC_COUNTER_BUFFER:
169 case GL_SHADER_STORAGE_BLOCK:
170 case GL_UNIFORM_BLOCK:
171 return true;
172 default:
173 return false;
174 }
175 }
176
177 case GL_LOCATION:
178 {
179 return ValidateLocationProgramInterface(programInterface);
180 }
181
182 case GL_NAME_LENGTH:
183 {
184 return ValidateNamedProgramInterface(programInterface);
185 }
186
187 case GL_OFFSET:
188 {
189 switch (programInterface)
190 {
191 case GL_BUFFER_VARIABLE:
192 case GL_UNIFORM:
193 return true;
194 default:
195 return false;
196 }
197 }
198
199 case GL_REFERENCED_BY_VERTEX_SHADER:
200 case GL_REFERENCED_BY_FRAGMENT_SHADER:
201 case GL_REFERENCED_BY_COMPUTE_SHADER:
202 {
203 switch (programInterface)
204 {
205 case GL_ATOMIC_COUNTER_BUFFER:
206 case GL_BUFFER_VARIABLE:
207 case GL_PROGRAM_INPUT:
208 case GL_PROGRAM_OUTPUT:
209 case GL_SHADER_STORAGE_BLOCK:
210 case GL_UNIFORM:
211 case GL_UNIFORM_BLOCK:
212 return true;
213 default:
214 return false;
215 }
216 }
217
218 case GL_TOP_LEVEL_ARRAY_SIZE:
219 case GL_TOP_LEVEL_ARRAY_STRIDE:
220 {
221 if (programInterface == GL_BUFFER_VARIABLE)
222 {
223 return true;
224 }
225 return false;
226 }
227
228 case GL_TYPE:
229 {
230 switch (programInterface)
231 {
232 case GL_BUFFER_VARIABLE:
233 case GL_PROGRAM_INPUT:
234 case GL_PROGRAM_OUTPUT:
235 case GL_TRANSFORM_FEEDBACK_VARYING:
236 case GL_UNIFORM:
237 return true;
238 default:
239 return false;
240 }
241 }
242
243 default:
244 return false;
245 }
246}
247
jchen10fd7c3b52017-03-21 15:36:03 +0800248bool ValidateProgramResourceIndex(const Program *programObject,
249 GLenum programInterface,
250 GLuint index)
251{
252 switch (programInterface)
253 {
254 case GL_PROGRAM_INPUT:
255 return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
256
257 case GL_PROGRAM_OUTPUT:
258 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
259
jchen10fd7c3b52017-03-21 15:36:03 +0800260 case GL_UNIFORM:
jchen10baf5d942017-08-28 20:45:48 +0800261 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
262
Jiajia Qin3a9090f2017-09-27 14:37:04 +0800263 case GL_BUFFER_VARIABLE:
264 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
265
266 case GL_SHADER_STORAGE_BLOCK:
267 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
268
jchen10fd7c3b52017-03-21 15:36:03 +0800269 case GL_UNIFORM_BLOCK:
jchen1058f67be2017-10-27 08:59:27 +0800270 return (index < programObject->getActiveUniformBlockCount());
271
272 case GL_ATOMIC_COUNTER_BUFFER:
273 return (index < programObject->getActiveAtomicCounterBufferCount());
274
jchen10fd7c3b52017-03-21 15:36:03 +0800275 case GL_TRANSFORM_FEEDBACK_VARYING:
jchen10910a3da2017-11-15 09:40:11 +0800276 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
jchen10fd7c3b52017-03-21 15:36:03 +0800277
278 default:
279 UNREACHABLE();
280 return false;
281 }
282}
283
Jamie Madill5b772312018-03-08 20:28:32 -0500284bool ValidateProgramUniform(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800285 GLenum valueType,
286 GLuint program,
287 GLint location,
288 GLsizei count)
289{
290 // Check for ES31 program uniform entry points
291 if (context->getClientVersion() < Version(3, 1))
292 {
293 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
294 return false;
295 }
296
297 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500298 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800299 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
300 ValidateUniformValue(context, valueType, uniform->type);
301}
302
Jamie Madill5b772312018-03-08 20:28:32 -0500303bool ValidateProgramUniformMatrix(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800304 GLenum valueType,
305 GLuint program,
306 GLint location,
307 GLsizei count,
308 GLboolean transpose)
309{
310 // Check for ES31 program uniform entry points
311 if (context->getClientVersion() < Version(3, 1))
312 {
313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
314 return false;
315 }
316
317 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500318 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800319 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
320 ValidateUniformMatrixValue(context, valueType, uniform->type);
321}
322
Jamie Madill5b772312018-03-08 20:28:32 -0500323bool ValidateVertexAttribFormatCommon(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800324 GLuint attribIndex,
325 GLint size,
326 GLenum type,
327 GLuint relativeOffset,
328 GLboolean pureInteger)
329{
330 if (context->getClientVersion() < ES_3_1)
331 {
332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
333 return false;
334 }
335
336 const Caps &caps = context->getCaps();
337 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
338 {
339 context->handleError(
340 InvalidValue()
341 << "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
342 return false;
343 }
344
345 // [OpenGL ES 3.1] Section 10.3.1 page 243:
346 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
347 if (context->getGLState().getVertexArrayId() == 0)
348 {
349 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
350 return false;
351 }
352
353 return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
354}
355
jchen1015015f72017-03-16 13:54:21 +0800356} // anonymous namespace
357
Martin Radev66fb8202016-07-28 11:45:20 +0300358bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
359{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400360 if (context->getClientVersion() < ES_3_1)
Martin Radev66fb8202016-07-28 11:45:20 +0300361 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Martin Radev66fb8202016-07-28 11:45:20 +0300363 return false;
364 }
365
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400366 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
367 {
368 return false;
369 }
370
371 return true;
372}
373
374bool ValidateGetBooleani_vRobustANGLE(Context *context,
375 GLenum target,
376 GLuint index,
377 GLsizei bufSize,
378 GLsizei *length,
379 GLboolean *data)
380{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400381 if (context->getClientVersion() < ES_3_1)
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400382 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700383 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400384 return false;
385 }
386
387 if (!ValidateRobustEntryPoint(context, bufSize))
388 {
389 return false;
390 }
391
Brandon Jonesd1049182018-03-28 10:02:20 -0700392 GLsizei numParams = 0;
393
394 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400395 {
396 return false;
397 }
398
Brandon Jonesd1049182018-03-28 10:02:20 -0700399 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Martin Radev66fb8202016-07-28 11:45:20 +0300400 {
401 return false;
402 }
403
Brandon Jonesd1049182018-03-28 10:02:20 -0700404 SetRobustLengthParam(length, numParams);
Martin Radev66fb8202016-07-28 11:45:20 +0300405 return true;
406}
407
Jamie Madill876429b2017-04-20 15:46:24 -0400408bool ValidateDrawIndirectBase(Context *context, GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800409{
410 if (context->getClientVersion() < ES_3_1)
411 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700412 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jiajia Qind9671222016-11-29 16:30:31 +0800413 return false;
414 }
415
416 // Here the third parameter 1 is only to pass the count validation.
417 if (!ValidateDrawBase(context, mode, 1))
418 {
419 return false;
420 }
421
422 const State &state = context->getGLState();
423
424 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
425 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
426 if (!state.getVertexArrayId())
427 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500428 context->handleError(InvalidOperation() << "zero is bound to VERTEX_ARRAY_BINDING");
Jiajia Qind9671222016-11-29 16:30:31 +0800429 return false;
430 }
431
Jamie Madill5b772312018-03-08 20:28:32 -0500432 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800433 if (!drawIndirectBuffer)
434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500435 context->handleError(InvalidOperation() << "zero is bound to DRAW_INDIRECT_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800436 return false;
437 }
438
439 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
440 // machine units, of uint.
441 GLint64 offset = reinterpret_cast<GLint64>(indirect);
442 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
443 {
444 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500445 InvalidValue()
446 << "indirect is not a multiple of the size, in basic machine units, of uint");
Jiajia Qind9671222016-11-29 16:30:31 +0800447 return false;
448 }
449
Martin Radev14a26ae2017-07-24 15:56:29 +0300450 // ANGLE_multiview spec, revision 1:
451 // An INVALID_OPERATION is generated by DrawArraysIndirect and DrawElementsIndirect if the
452 // number of views in the draw framebuffer is greater than 1.
453 const Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
454 ASSERT(drawFramebuffer != nullptr);
455 if (drawFramebuffer->getNumViews() > 1)
456 {
457 context->handleError(
458 InvalidOperation()
459 << "The number of views in the active draw framebuffer is greater than 1.");
460 return false;
461 }
462
Jiajia Qind9671222016-11-29 16:30:31 +0800463 return true;
464}
465
Jamie Madill876429b2017-04-20 15:46:24 -0400466bool ValidateDrawArraysIndirect(Context *context, GLenum mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800467{
468 const State &state = context->getGLState();
Jamie Madill5b772312018-03-08 20:28:32 -0500469 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
Jiajia Qind9671222016-11-29 16:30:31 +0800470 if (curTransformFeedback && curTransformFeedback->isActive() &&
471 !curTransformFeedback->isPaused())
472 {
473 // An INVALID_OPERATION error is generated if transform feedback is active and not paused.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500474 context->handleError(InvalidOperation() << "transform feedback is active and not paused.");
Jiajia Qind9671222016-11-29 16:30:31 +0800475 return false;
476 }
477
478 if (!ValidateDrawIndirectBase(context, mode, indirect))
479 return false;
480
Jamie Madill5b772312018-03-08 20:28:32 -0500481 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800482 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
483 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
484 // which's size is 4 * sizeof(uint).
485 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
486 if (!checkedSum.IsValid() ||
487 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
488 {
489 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500490 InvalidOperation()
491 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800492 return false;
493 }
494
495 return true;
496}
497
Jamie Madill876429b2017-04-20 15:46:24 -0400498bool ValidateDrawElementsIndirect(Context *context, GLenum mode, GLenum type, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800499{
500 if (!ValidateDrawElementsBase(context, type))
501 return false;
502
503 const State &state = context->getGLState();
504 const VertexArray *vao = state.getVertexArray();
Jamie Madill5b772312018-03-08 20:28:32 -0500505 Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
Jiajia Qind9671222016-11-29 16:30:31 +0800506 if (!elementArrayBuffer)
507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500508 context->handleError(InvalidOperation() << "zero is bound to ELEMENT_ARRAY_BUFFER");
Jiajia Qind9671222016-11-29 16:30:31 +0800509 return false;
510 }
511
512 if (!ValidateDrawIndirectBase(context, mode, indirect))
513 return false;
514
Jamie Madill5b772312018-03-08 20:28:32 -0500515 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800516 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
517 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
518 // which's size is 5 * sizeof(uint).
519 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
520 if (!checkedSum.IsValid() ||
521 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
522 {
523 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500524 InvalidOperation()
525 << "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800526 return false;
527 }
528
529 return true;
530}
531
Jiajia Qin5451d532017-11-16 17:16:34 +0800532bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0)
533{
534 return ValidateProgramUniform1iv(context, program, location, 1, &v0);
535}
536
537bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1)
538{
539 GLint xy[2] = {v0, v1};
540 return ValidateProgramUniform2iv(context, program, location, 1, xy);
541}
542
543bool ValidateProgramUniform3i(Context *context,
544 GLuint program,
545 GLint location,
546 GLint v0,
547 GLint v1,
548 GLint v2)
549{
550 GLint xyz[3] = {v0, v1, v2};
551 return ValidateProgramUniform3iv(context, program, location, 1, xyz);
552}
553
554bool ValidateProgramUniform4i(Context *context,
555 GLuint program,
556 GLint location,
557 GLint v0,
558 GLint v1,
559 GLint v2,
560 GLint v3)
561{
562 GLint xyzw[4] = {v0, v1, v2, v3};
563 return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
564}
565
566bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0)
567{
568 return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
569}
570
571bool ValidateProgramUniform2ui(Context *context,
572 GLuint program,
573 GLint location,
574 GLuint v0,
575 GLuint v1)
576{
577 GLuint xy[2] = {v0, v1};
578 return ValidateProgramUniform2uiv(context, program, location, 1, xy);
579}
580
581bool ValidateProgramUniform3ui(Context *context,
582 GLuint program,
583 GLint location,
584 GLuint v0,
585 GLuint v1,
586 GLuint v2)
587{
588 GLuint xyz[3] = {v0, v1, v2};
589 return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
590}
591
592bool ValidateProgramUniform4ui(Context *context,
593 GLuint program,
594 GLint location,
595 GLuint v0,
596 GLuint v1,
597 GLuint v2,
598 GLuint v3)
599{
600 GLuint xyzw[4] = {v0, v1, v2, v3};
601 return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
602}
603
604bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0)
605{
606 return ValidateProgramUniform1fv(context, program, location, 1, &v0);
607}
608
609bool ValidateProgramUniform2f(Context *context,
610 GLuint program,
611 GLint location,
612 GLfloat v0,
613 GLfloat v1)
614{
615 GLfloat xy[2] = {v0, v1};
616 return ValidateProgramUniform2fv(context, program, location, 1, xy);
617}
618
619bool ValidateProgramUniform3f(Context *context,
620 GLuint program,
621 GLint location,
622 GLfloat v0,
623 GLfloat v1,
624 GLfloat v2)
625{
626 GLfloat xyz[3] = {v0, v1, v2};
627 return ValidateProgramUniform3fv(context, program, location, 1, xyz);
628}
629
630bool ValidateProgramUniform4f(Context *context,
631 GLuint program,
632 GLint location,
633 GLfloat v0,
634 GLfloat v1,
635 GLfloat v2,
636 GLfloat v3)
637{
638 GLfloat xyzw[4] = {v0, v1, v2, v3};
639 return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
640}
641
642bool ValidateProgramUniform1iv(Context *context,
643 GLuint program,
644 GLint location,
645 GLsizei count,
646 const GLint *value)
647{
648 // Check for ES31 program uniform entry points
649 if (context->getClientVersion() < Version(3, 1))
650 {
651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
652 return false;
653 }
654
655 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500656 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800657 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
658 ValidateUniform1ivValue(context, uniform->type, count, value);
659}
660
661bool ValidateProgramUniform2iv(Context *context,
662 GLuint program,
663 GLint location,
664 GLsizei count,
665 const GLint *value)
666{
667 return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
668}
669
670bool ValidateProgramUniform3iv(Context *context,
671 GLuint program,
672 GLint location,
673 GLsizei count,
674 const GLint *value)
675{
676 return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
677}
678
679bool ValidateProgramUniform4iv(Context *context,
680 GLuint program,
681 GLint location,
682 GLsizei count,
683 const GLint *value)
684{
685 return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
686}
687
688bool ValidateProgramUniform1uiv(Context *context,
689 GLuint program,
690 GLint location,
691 GLsizei count,
692 const GLuint *value)
693{
694 return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
695}
696
697bool ValidateProgramUniform2uiv(Context *context,
698 GLuint program,
699 GLint location,
700 GLsizei count,
701 const GLuint *value)
702{
703 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
704}
705
706bool ValidateProgramUniform3uiv(Context *context,
707 GLuint program,
708 GLint location,
709 GLsizei count,
710 const GLuint *value)
711{
712 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
713}
714
715bool ValidateProgramUniform4uiv(Context *context,
716 GLuint program,
717 GLint location,
718 GLsizei count,
719 const GLuint *value)
720{
721 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
722}
723
724bool ValidateProgramUniform1fv(Context *context,
725 GLuint program,
726 GLint location,
727 GLsizei count,
728 const GLfloat *value)
729{
730 return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
731}
732
733bool ValidateProgramUniform2fv(Context *context,
734 GLuint program,
735 GLint location,
736 GLsizei count,
737 const GLfloat *value)
738{
739 return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
740}
741
742bool ValidateProgramUniform3fv(Context *context,
743 GLuint program,
744 GLint location,
745 GLsizei count,
746 const GLfloat *value)
747{
748 return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
749}
750
751bool ValidateProgramUniform4fv(Context *context,
752 GLuint program,
753 GLint location,
754 GLsizei count,
755 const GLfloat *value)
756{
757 return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
758}
759
760bool ValidateProgramUniformMatrix2fv(Context *context,
761 GLuint program,
762 GLint location,
763 GLsizei count,
764 GLboolean transpose,
765 const GLfloat *value)
766{
767 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
768 transpose);
769}
770
771bool ValidateProgramUniformMatrix3fv(Context *context,
772 GLuint program,
773 GLint location,
774 GLsizei count,
775 GLboolean transpose,
776 const GLfloat *value)
777{
778 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
779 transpose);
780}
781
782bool ValidateProgramUniformMatrix4fv(Context *context,
783 GLuint program,
784 GLint location,
785 GLsizei count,
786 GLboolean transpose,
787 const GLfloat *value)
788{
789 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
790 transpose);
791}
792
793bool ValidateProgramUniformMatrix2x3fv(Context *context,
794 GLuint program,
795 GLint location,
796 GLsizei count,
797 GLboolean transpose,
798 const GLfloat *value)
799{
800 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
801 transpose);
802}
803
804bool ValidateProgramUniformMatrix3x2fv(Context *context,
805 GLuint program,
806 GLint location,
807 GLsizei count,
808 GLboolean transpose,
809 const GLfloat *value)
810{
811 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
812 transpose);
813}
814
815bool ValidateProgramUniformMatrix2x4fv(Context *context,
816 GLuint program,
817 GLint location,
818 GLsizei count,
819 GLboolean transpose,
820 const GLfloat *value)
821{
822 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
823 transpose);
824}
825
826bool ValidateProgramUniformMatrix4x2fv(Context *context,
827 GLuint program,
828 GLint location,
829 GLsizei count,
830 GLboolean transpose,
831 const GLfloat *value)
832{
833 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
834 transpose);
835}
836
837bool ValidateProgramUniformMatrix3x4fv(Context *context,
838 GLuint program,
839 GLint location,
840 GLsizei count,
841 GLboolean transpose,
842 const GLfloat *value)
843{
844 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
845 transpose);
846}
847
848bool ValidateProgramUniformMatrix4x3fv(Context *context,
849 GLuint program,
850 GLint location,
851 GLsizei count,
852 GLboolean transpose,
853 const GLfloat *value)
854{
855 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
856 transpose);
857}
858
He Yunchao11b038b2016-11-22 21:24:04 +0800859bool ValidateGetTexLevelParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800860 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800861 GLint level,
862 GLenum pname,
863 GLsizei *length)
864{
865 if (context->getClientVersion() < ES_3_1)
866 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700867 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
He Yunchao11b038b2016-11-22 21:24:04 +0800868 return false;
869 }
870
871 if (length)
872 {
873 *length = 0;
874 }
875
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800876 TextureType type = TextureTargetToType(target);
877
878 if (!ValidTexLevelDestinationTarget(context, type))
He Yunchao11b038b2016-11-22 21:24:04 +0800879 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700880 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
He Yunchao11b038b2016-11-22 21:24:04 +0800881 return false;
882 }
883
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800884 if (context->getTargetTexture(type) == nullptr)
He Yunchao11b038b2016-11-22 21:24:04 +0800885 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500886 context->handleError(InvalidEnum() << "No texture bound.");
He Yunchao11b038b2016-11-22 21:24:04 +0800887 return false;
888 }
889
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800890 if (!ValidMipLevel(context, type, level))
He Yunchao11b038b2016-11-22 21:24:04 +0800891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500892 context->handleError(InvalidValue());
He Yunchao11b038b2016-11-22 21:24:04 +0800893 return false;
894 }
895
896 switch (pname)
897 {
898 case GL_TEXTURE_RED_TYPE:
899 case GL_TEXTURE_GREEN_TYPE:
900 case GL_TEXTURE_BLUE_TYPE:
901 case GL_TEXTURE_ALPHA_TYPE:
902 case GL_TEXTURE_DEPTH_TYPE:
903 break;
904 case GL_TEXTURE_RED_SIZE:
905 case GL_TEXTURE_GREEN_SIZE:
906 case GL_TEXTURE_BLUE_SIZE:
907 case GL_TEXTURE_ALPHA_SIZE:
908 case GL_TEXTURE_DEPTH_SIZE:
909 case GL_TEXTURE_STENCIL_SIZE:
910 case GL_TEXTURE_SHARED_SIZE:
911 break;
912 case GL_TEXTURE_INTERNAL_FORMAT:
913 case GL_TEXTURE_WIDTH:
914 case GL_TEXTURE_HEIGHT:
915 case GL_TEXTURE_DEPTH:
916 break;
917 case GL_TEXTURE_SAMPLES:
918 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
919 break;
920 case GL_TEXTURE_COMPRESSED:
921 break;
922 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700923 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
He Yunchao11b038b2016-11-22 21:24:04 +0800924 return false;
925 }
926
927 if (length)
928 {
929 *length = 1;
930 }
931 return true;
932}
933
934bool ValidateGetTexLevelParameterfv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800935 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800936 GLint level,
937 GLenum pname,
938 GLfloat *params)
939{
940 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
941}
942
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700943bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
944 TextureTarget target,
945 GLint level,
946 GLenum pname,
947 GLsizei bufSize,
948 GLsizei *length,
949 GLfloat *params)
950{
951 UNIMPLEMENTED();
952 return false;
953}
954
He Yunchao11b038b2016-11-22 21:24:04 +0800955bool ValidateGetTexLevelParameteriv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800956 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800957 GLint level,
958 GLenum pname,
959 GLint *params)
960{
961 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
962}
963
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700964bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
965 TextureTarget target,
966 GLint level,
967 GLenum pname,
968 GLsizei bufSize,
969 GLsizei *length,
970 GLint *params)
971{
972 UNIMPLEMENTED();
973 return false;
974}
975
Jiajia Qin5451d532017-11-16 17:16:34 +0800976bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800977 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800978 GLsizei samples,
979 GLint internalFormat,
980 GLsizei width,
981 GLsizei height,
982 GLboolean fixedSampleLocations)
983{
984 if (context->getClientVersion() < ES_3_1)
985 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700986 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800987 return false;
988 }
989
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800990 if (target != TextureType::_2DMultisample)
JiangYizhoubddc46b2016-12-09 09:50:51 +0800991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500992 context->handleError(InvalidEnum() << "Target must be TEXTURE_2D_MULTISAMPLE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +0800993 return false;
994 }
995
996 if (width < 1 || height < 1)
997 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700998 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800999 return false;
1000 }
1001
1002 const Caps &caps = context->getCaps();
1003 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1004 static_cast<GLuint>(height) > caps.max2DTextureSize)
1005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001006 context
1007 ->handleError(InvalidValue()
1008 << "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001009 return false;
1010 }
1011
1012 if (samples == 0)
1013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001014 context->handleError(InvalidValue() << "Samples may not be zero.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001015 return false;
1016 }
1017
1018 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
1019 if (!formatCaps.renderable)
1020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001021 context->handleError(InvalidEnum() << "SizedInternalformat must be color-renderable, "
1022 "depth-renderable, or stencil-renderable.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001023 return false;
1024 }
1025
1026 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
1027 // is one of the unsized base internalformats listed in table 8.11.
Geoff Langca271392017-04-05 12:30:00 -04001028 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
1029 if (formatInfo.internalFormat == GL_NONE)
JiangYizhoubddc46b2016-12-09 09:50:51 +08001030 {
1031 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001032 InvalidEnum()
1033 << "Internalformat is one of the unsupported unsized base internalformats.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001034 return false;
1035 }
1036
1037 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
1038 {
1039 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001040 InvalidOperation()
1041 << "Samples must not be greater than maximum supported value for the format.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001042 return false;
1043 }
1044
1045 Texture *texture = context->getTargetTexture(target);
1046 if (!texture || texture->id() == 0)
1047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001048 context->handleError(InvalidOperation() << "Zero is bound to target.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001049 return false;
1050 }
1051
1052 if (texture->getImmutableFormat())
1053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001054 context->handleError(InvalidOperation() << "The value of TEXTURE_IMMUTABLE_FORMAT for "
1055 "the texture currently bound to target on "
1056 "the active texture unit is true.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001057 return false;
1058 }
1059
1060 return true;
1061}
1062
1063bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
1064{
1065 if (context->getClientVersion() < ES_3_1)
1066 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001067 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +08001068 return false;
1069 }
1070
1071 if (pname != GL_SAMPLE_POSITION)
1072 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001073 context->handleError(InvalidEnum() << "Pname must be SAMPLE_POSITION.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001074 return false;
1075 }
1076
JiangYizhou5b03f472017-01-09 10:22:53 +08001077 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05001078 GLint samples = 0;
1079 ANGLE_VALIDATION_TRY(framebuffer->getSamples(context, &samples));
JiangYizhou5b03f472017-01-09 10:22:53 +08001080
Jamie Madille98b1b52018-03-08 09:47:23 -05001081 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +08001082 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001083 context->handleError(InvalidValue() << "Index must be less than the value of SAMPLES.");
JiangYizhoubddc46b2016-12-09 09:50:51 +08001084 return false;
1085 }
1086
1087 return true;
1088}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001089
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001090bool ValidateGetMultisamplefvRobustANGLE(Context *context,
1091 GLenum pname,
1092 GLuint index,
1093 GLsizei bufSize,
1094 GLsizei *length,
1095 GLfloat *val)
1096{
1097 UNIMPLEMENTED();
1098 return false;
1099}
1100
Jiajia Qin5451d532017-11-16 17:16:34 +08001101bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001102{
1103 if (context->getClientVersion() < ES_3_1)
1104 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001105 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001106 return false;
1107 }
1108
Geoff Lange8afa902017-09-27 15:00:43 -04001109 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001111 context->handleError(InvalidEnum() << "Invalid framebuffer target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001112 return false;
1113 }
1114
1115 switch (pname)
1116 {
1117 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1118 {
1119 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1120 if (param < 0 || param > maxWidth)
1121 {
1122 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001123 InvalidValue()
1124 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001125 return false;
1126 }
1127 break;
1128 }
1129 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1130 {
1131 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1132 if (param < 0 || param > maxHeight)
1133 {
1134 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001135 InvalidValue()
1136 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001137 return false;
1138 }
1139 break;
1140 }
1141 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1142 {
1143 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1144 if (param < 0 || param > maxSamples)
1145 {
1146 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001147 InvalidValue()
1148 << "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001149 return false;
1150 }
1151 break;
1152 }
1153 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1154 {
1155 break;
1156 }
1157 default:
1158 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001159 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001160 return false;
1161 }
1162 }
1163
1164 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1165 ASSERT(framebuffer);
1166 if (framebuffer->id() == 0)
1167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001168 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001169 return false;
1170 }
1171 return true;
1172}
1173
Jiajia Qin5451d532017-11-16 17:16:34 +08001174bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001175{
1176 if (context->getClientVersion() < ES_3_1)
1177 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001178 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001179 return false;
1180 }
1181
Geoff Lange8afa902017-09-27 15:00:43 -04001182 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001183 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001184 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001185 return false;
1186 }
1187
1188 switch (pname)
1189 {
1190 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1191 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1192 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1193 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1194 break;
1195 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001196 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001197 return false;
1198 }
1199
1200 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1201 ASSERT(framebuffer);
1202
1203 if (framebuffer->id() == 0)
1204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001205 context->handleError(InvalidOperation() << "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001206 return false;
1207 }
1208 return true;
1209}
1210
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001211bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1212 GLenum target,
1213 GLenum pname,
1214 GLsizei bufSize,
1215 GLsizei *length,
1216 GLint *params)
1217{
1218 UNIMPLEMENTED();
1219 return false;
1220}
1221
jchen1015015f72017-03-16 13:54:21 +08001222bool ValidateGetProgramResourceIndex(Context *context,
1223 GLuint program,
1224 GLenum programInterface,
1225 const GLchar *name)
1226{
1227 if (context->getClientVersion() < ES_3_1)
1228 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001229 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen1015015f72017-03-16 13:54:21 +08001230 return false;
1231 }
1232
1233 Program *programObject = GetValidProgram(context, program);
1234 if (programObject == nullptr)
1235 {
1236 return false;
1237 }
1238
1239 if (!ValidateNamedProgramInterface(programInterface))
1240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001241 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1242 << std::uppercase << programInterface);
jchen1015015f72017-03-16 13:54:21 +08001243 return false;
1244 }
Shao80957d92017-02-20 21:25:59 +08001245
1246 return true;
1247}
1248
Jamie Madill5b772312018-03-08 20:28:32 -05001249bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001250 GLuint bindingIndex,
1251 GLuint buffer,
1252 GLintptr offset,
1253 GLsizei stride)
1254{
1255 if (context->getClientVersion() < ES_3_1)
1256 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001258 return false;
1259 }
1260
1261 if (!context->isBufferGenerated(buffer))
1262 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001263 context->handleError(InvalidOperation() << "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001264 return false;
1265 }
1266
1267 const Caps &caps = context->getCaps();
1268 if (bindingIndex >= caps.maxVertexAttribBindings)
1269 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001270 context->handleError(InvalidValue()
1271 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001272 return false;
1273 }
1274
1275 if (offset < 0)
1276 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001277 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001278 return false;
1279 }
1280
1281 if (stride < 0 || stride > caps.maxVertexAttribStride)
1282 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001283 context->handleError(InvalidValue()
1284 << "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001285 return false;
1286 }
1287
1288 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1289 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1290 if (context->getGLState().getVertexArrayId() == 0)
1291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001292 context->handleError(InvalidOperation() << "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001293 return false;
1294 }
1295
1296 return true;
1297}
1298
Jamie Madill5b772312018-03-08 20:28:32 -05001299bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001300{
1301 if (context->getClientVersion() < ES_3_1)
1302 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001303 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001304 return false;
1305 }
1306
1307 const Caps &caps = context->getCaps();
1308 if (bindingIndex >= caps.maxVertexAttribBindings)
1309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001310 context->handleError(InvalidValue()
1311 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001312 return false;
1313 }
1314
1315 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1316 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1317 if (context->getGLState().getVertexArrayId() == 0)
1318 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001319 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001320 return false;
1321 }
1322
1323 return true;
1324}
1325
Jamie Madill5b772312018-03-08 20:28:32 -05001326bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001327 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001328 GLint size,
1329 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001330 GLboolean normalized,
1331 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001332{
Jiajia Qin5451d532017-11-16 17:16:34 +08001333 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1334 false);
1335}
Shao80957d92017-02-20 21:25:59 +08001336
Jamie Madill5b772312018-03-08 20:28:32 -05001337bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001338 GLuint attribindex,
1339 GLint size,
1340 GLenum type,
1341 GLuint relativeoffset)
1342{
1343 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001344}
1345
Jamie Madill5b772312018-03-08 20:28:32 -05001346bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001347{
1348 if (context->getClientVersion() < ES_3_1)
1349 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Shao80957d92017-02-20 21:25:59 +08001351 return false;
1352 }
1353
1354 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1355 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1356 if (context->getGLState().getVertexArrayId() == 0)
1357 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001358 context->handleError(InvalidOperation() << "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001359 return false;
1360 }
1361
1362 const Caps &caps = context->getCaps();
1363 if (attribIndex >= caps.maxVertexAttributes)
1364 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001365 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001366 return false;
1367 }
1368
1369 if (bindingIndex >= caps.maxVertexAttribBindings)
1370 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001371 context->handleError(InvalidValue()
1372 << "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001373 return false;
1374 }
1375
jchen1015015f72017-03-16 13:54:21 +08001376 return true;
1377}
1378
jchen10fd7c3b52017-03-21 15:36:03 +08001379bool ValidateGetProgramResourceName(Context *context,
1380 GLuint program,
1381 GLenum programInterface,
1382 GLuint index,
1383 GLsizei bufSize,
1384 GLsizei *length,
1385 GLchar *name)
1386{
1387 if (context->getClientVersion() < ES_3_1)
1388 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001390 return false;
1391 }
1392
1393 Program *programObject = GetValidProgram(context, program);
1394 if (programObject == nullptr)
1395 {
1396 return false;
1397 }
1398
1399 if (!ValidateNamedProgramInterface(programInterface))
1400 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001401 context->handleError(InvalidEnum() << "Invalid program interface: 0x" << std::hex
1402 << std::uppercase << programInterface);
jchen10fd7c3b52017-03-21 15:36:03 +08001403 return false;
1404 }
1405
1406 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1407 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001408 context->handleError(InvalidValue() << "Invalid index: " << index);
jchen10fd7c3b52017-03-21 15:36:03 +08001409 return false;
1410 }
1411
1412 if (bufSize < 0)
1413 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001414 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001415 return false;
1416 }
1417
1418 return true;
1419}
1420
Xinghua Cao2b396592017-03-29 15:36:04 +08001421bool ValidateDispatchCompute(Context *context,
1422 GLuint numGroupsX,
1423 GLuint numGroupsY,
1424 GLuint numGroupsZ)
1425{
1426 if (context->getClientVersion() < ES_3_1)
1427 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001428 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001429 return false;
1430 }
1431
1432 const State &state = context->getGLState();
1433 Program *program = state.getProgram();
1434
Jiawei Shao385b3e02018-03-21 09:43:28 +08001435 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001436 {
Qin Jiajia62fcf622017-11-30 16:16:12 +08001437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001438 return false;
1439 }
1440
1441 const Caps &caps = context->getCaps();
1442 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1443 {
1444 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001445 InvalidValue() << "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]="
1446 << caps.maxComputeWorkGroupCount[0]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001447 return false;
1448 }
1449 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1450 {
1451 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001452 InvalidValue() << "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]="
1453 << caps.maxComputeWorkGroupCount[1]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001454 return false;
1455 }
1456 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1457 {
1458 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 InvalidValue() << "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]="
1460 << caps.maxComputeWorkGroupCount[2]);
Xinghua Cao2b396592017-03-29 15:36:04 +08001461 return false;
1462 }
1463
1464 return true;
1465}
1466
Jiajia Qin5451d532017-11-16 17:16:34 +08001467bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1468{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001469 if (context->getClientVersion() < ES_3_1)
1470 {
1471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1472 return false;
1473 }
1474
1475 const State &state = context->getGLState();
1476 Program *program = state.getProgram();
1477
Jiawei Shao385b3e02018-03-21 09:43:28 +08001478 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001479 {
1480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
1481 return false;
1482 }
1483
Qin Jiajia62fcf622017-11-30 16:16:12 +08001484 if (indirect < 0)
1485 {
1486 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
1487 return false;
1488 }
1489
1490 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1491 {
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001492 ANGLE_VALIDATION_ERR(context, InvalidValue(), OffsetMustBeMultipleOfUint);
1493 return false;
1494 }
1495
Jamie Madill5b772312018-03-08 20:28:32 -05001496 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001497 if (!dispatchIndirectBuffer)
1498 {
1499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001500 return false;
1501 }
1502
1503 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1504 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1505 if (!checkedSum.IsValid() ||
1506 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1507 {
1508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
1509 return false;
1510 }
1511
1512 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001513}
1514
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001515bool ValidateBindImageTexture(Context *context,
1516 GLuint unit,
1517 GLuint texture,
1518 GLint level,
1519 GLboolean layered,
1520 GLint layer,
1521 GLenum access,
1522 GLenum format)
1523{
1524 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1525 if (unit >= maxImageUnits)
1526 {
1527 context->handleError(InvalidValue()
1528 << "unit cannot be greater than or equal than MAX_IMAGE_UNITS = "
1529 << maxImageUnits);
1530 return false;
1531 }
1532
1533 if (level < 0)
1534 {
1535 context->handleError(InvalidValue() << "level is negative.");
1536 return false;
1537 }
1538
1539 if (layer < 0)
1540 {
1541 context->handleError(InvalidValue() << "layer is negative.");
1542 return false;
1543 }
1544
1545 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1546 {
1547 context->handleError(InvalidEnum() << "access is not one of the supported tokens.");
1548 return false;
1549 }
1550
1551 switch (format)
1552 {
1553 case GL_RGBA32F:
1554 case GL_RGBA16F:
1555 case GL_R32F:
1556 case GL_RGBA32UI:
1557 case GL_RGBA16UI:
1558 case GL_RGBA8UI:
1559 case GL_R32UI:
1560 case GL_RGBA32I:
1561 case GL_RGBA16I:
1562 case GL_RGBA8I:
1563 case GL_R32I:
1564 case GL_RGBA8:
1565 case GL_RGBA8_SNORM:
1566 break;
1567 default:
1568 context->handleError(InvalidValue()
1569 << "format is not one of supported image unit formats.");
1570 return false;
1571 }
1572
1573 if (texture != 0)
1574 {
1575 Texture *tex = context->getTexture(texture);
1576
1577 if (tex == nullptr)
1578 {
1579 context->handleError(InvalidValue()
1580 << "texture is not the name of an existing texture object.");
1581 return false;
1582 }
1583
1584 if (!tex->getImmutableFormat())
1585 {
1586 context->handleError(InvalidOperation()
1587 << "texture is not the name of an immutable texture object.");
1588 return false;
1589 }
1590 }
1591
1592 return true;
1593}
jchen10191381f2017-04-11 13:59:04 +08001594
1595bool ValidateGetProgramResourceLocation(Context *context,
1596 GLuint program,
1597 GLenum programInterface,
1598 const GLchar *name)
1599{
1600 if (context->getClientVersion() < ES_3_1)
1601 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001602 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10191381f2017-04-11 13:59:04 +08001603 return false;
1604 }
1605
1606 Program *programObject = GetValidProgram(context, program);
1607 if (programObject == nullptr)
1608 {
1609 return false;
1610 }
1611
1612 if (!programObject->isLinked())
1613 {
1614 context->handleError(InvalidOperation() << "Program is not successfully linked.");
1615 return false;
1616 }
1617
1618 if (!ValidateLocationProgramInterface(programInterface))
1619 {
1620 context->handleError(InvalidEnum() << "Invalid program interface.");
1621 return false;
1622 }
1623 return true;
1624}
1625
jchen10880683b2017-04-12 16:21:55 +08001626bool ValidateGetProgramResourceiv(Context *context,
1627 GLuint program,
1628 GLenum programInterface,
1629 GLuint index,
1630 GLsizei propCount,
1631 const GLenum *props,
1632 GLsizei bufSize,
1633 GLsizei *length,
1634 GLint *params)
1635{
1636 if (context->getClientVersion() < ES_3_1)
1637 {
jchen10d9cd7b72017-08-30 15:04:25 +08001638 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
jchen10880683b2017-04-12 16:21:55 +08001639 return false;
1640 }
1641
1642 Program *programObject = GetValidProgram(context, program);
1643 if (programObject == nullptr)
1644 {
1645 return false;
1646 }
1647 if (!ValidateProgramInterface(programInterface))
1648 {
1649 context->handleError(InvalidEnum() << "Invalid program interface.");
1650 return false;
1651 }
1652 if (propCount <= 0)
1653 {
1654 context->handleError(InvalidValue() << "Invalid propCount.");
1655 return false;
1656 }
1657 if (bufSize < 0)
1658 {
1659 context->handleError(InvalidValue() << "Invalid bufSize.");
1660 return false;
1661 }
1662 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1663 {
1664 context->handleError(InvalidValue() << "Invalid index: " << index);
1665 return false;
1666 }
1667 for (GLsizei i = 0; i < propCount; i++)
1668 {
1669 if (!ValidateProgramResourceProperty(props[i]))
1670 {
1671 context->handleError(InvalidEnum() << "Invalid prop.");
1672 return false;
1673 }
1674 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1675 {
1676 context->handleError(InvalidOperation() << "Not an allowed prop for interface");
1677 return false;
1678 }
1679 }
1680 return true;
1681}
1682
jchen10d9cd7b72017-08-30 15:04:25 +08001683bool ValidateGetProgramInterfaceiv(Context *context,
1684 GLuint program,
1685 GLenum programInterface,
1686 GLenum pname,
1687 GLint *params)
1688{
1689 if (context->getClientVersion() < ES_3_1)
1690 {
1691 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1692 return false;
1693 }
1694
1695 Program *programObject = GetValidProgram(context, program);
1696 if (programObject == nullptr)
1697 {
1698 return false;
1699 }
1700
1701 if (!ValidateProgramInterface(programInterface))
1702 {
1703 context->handleError(InvalidEnum() << "Invalid program interface.");
1704 return false;
1705 }
1706
1707 switch (pname)
1708 {
1709 case GL_ACTIVE_RESOURCES:
1710 case GL_MAX_NAME_LENGTH:
1711 case GL_MAX_NUM_ACTIVE_VARIABLES:
1712 break;
1713
1714 default:
1715 context->handleError(InvalidEnum() << "Unknown property of program interface.");
1716 return false;
1717 }
1718
1719 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1720 {
1721 context->handleError(InvalidOperation()
1722 << "Active atomic counter resources are not assigned name strings.");
1723 return false;
1724 }
1725
1726 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1727 {
1728 switch (programInterface)
1729 {
1730 case GL_ATOMIC_COUNTER_BUFFER:
1731 case GL_SHADER_STORAGE_BLOCK:
1732 case GL_UNIFORM_BLOCK:
1733 break;
1734
1735 default:
1736 context->handleError(
1737 InvalidOperation()
1738 << "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
1739 return false;
1740 }
1741 }
1742
1743 return true;
1744}
1745
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001746bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1747 GLuint program,
1748 GLenum programInterface,
1749 GLenum pname,
1750 GLsizei bufSize,
1751 GLsizei *length,
1752 GLint *params)
1753{
1754 UNIMPLEMENTED();
1755 return false;
1756}
1757
Yunchao Hea336b902017-08-02 16:05:21 +08001758static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1759{
1760 if (context->getClientVersion() < ES_3_1)
1761 {
1762 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1763 return false;
1764 }
1765
1766 return ValidateGenOrDelete(context, n);
1767}
1768
1769bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1770{
1771 return ValidateGenOrDeleteES31(context, n);
1772}
1773
1774bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1775{
1776 return ValidateGenOrDeleteES31(context, n);
1777}
1778
1779bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1780{
1781 if (context->getClientVersion() < ES_3_1)
1782 {
1783 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1784 return false;
1785 }
1786
1787 if (!context->isProgramPipelineGenerated(pipeline))
1788 {
1789 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
1790 return false;
1791 }
1792
1793 return true;
1794}
1795
1796bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1797{
1798 if (context->getClientVersion() < ES_3_1)
1799 {
1800 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1801 return false;
1802 }
1803
1804 return true;
1805}
1806
Jiajia Qin5451d532017-11-16 17:16:34 +08001807bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1808{
1809 UNIMPLEMENTED();
1810 return false;
1811}
1812
1813bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1814{
1815 UNIMPLEMENTED();
1816 return false;
1817}
1818
1819bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001820 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001821 GLsizei count,
1822 const GLchar *const *strings)
1823{
1824 UNIMPLEMENTED();
1825 return false;
1826}
1827
1828bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1829{
1830 UNIMPLEMENTED();
1831 return false;
1832}
1833
1834bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1835{
1836 UNIMPLEMENTED();
1837 return false;
1838}
1839
1840bool ValidateGetProgramPipelineInfoLog(Context *context,
1841 GLuint pipeline,
1842 GLsizei bufSize,
1843 GLsizei *length,
1844 GLchar *infoLog)
1845{
1846 UNIMPLEMENTED();
1847 return false;
1848}
1849
1850bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1851{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001852 if (context->getClientVersion() < ES_3_1)
1853 {
1854 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1855 return false;
1856 }
1857
1858 if (barriers == GL_ALL_BARRIER_BITS)
1859 {
1860 return true;
1861 }
1862
1863 GLbitfield supported_barrier_bits =
1864 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1865 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1866 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1867 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1868 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1869 if ((barriers & ~supported_barrier_bits) != 0)
1870 {
1871 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1872 return false;
1873 }
1874
1875 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001876}
1877
1878bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1879{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001880 if (context->getClientVersion() < ES_3_1)
1881 {
1882 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1883 return false;
1884 }
1885
1886 if (barriers == GL_ALL_BARRIER_BITS)
1887 {
1888 return true;
1889 }
1890
1891 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1892 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1893 GL_SHADER_STORAGE_BARRIER_BIT |
1894 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1895 if ((barriers & ~supported_barrier_bits) != 0)
1896 {
1897 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMemoryBarrierBit);
1898 return false;
1899 }
1900
1901 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001902}
1903
1904bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001905{
1906 if (context->getClientVersion() < ES_3_1)
1907 {
1908 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
1909 return false;
1910 }
1911
1912 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1913 {
1914 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidSampleMaskNumber);
1915 return false;
1916 }
1917
1918 return true;
1919}
1920
Martin Radev66fb8202016-07-28 11:45:20 +03001921} // namespace gl