blob: 5e8faff826c7203cc9ecb47fa8179cf4c2347255 [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
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES31_autogen.h"
Martin Radev66fb8202016-07-28 11:45:20 +030010
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"
Jamie Madill778bf092018-11-14 09:54:36 -050016#include "libANGLE/validationES2_autogen.h"
17#include "libANGLE/validationES3_autogen.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{
Jamie Madille0472f32018-11-27 16:32:45 -050025using namespace err;
Martin Radev66fb8202016-07-28 11:45:20 +030026
jchen1015015f72017-03-16 13:54:21 +080027namespace
28{
29
30bool ValidateNamedProgramInterface(GLenum programInterface)
31{
32 switch (programInterface)
33 {
34 case GL_UNIFORM:
35 case GL_UNIFORM_BLOCK:
36 case GL_PROGRAM_INPUT:
37 case GL_PROGRAM_OUTPUT:
38 case GL_TRANSFORM_FEEDBACK_VARYING:
39 case GL_BUFFER_VARIABLE:
40 case GL_SHADER_STORAGE_BLOCK:
41 return true;
42 default:
43 return false;
44 }
45}
46
jchen10191381f2017-04-11 13:59:04 +080047bool ValidateLocationProgramInterface(GLenum programInterface)
48{
49 switch (programInterface)
50 {
51 case GL_UNIFORM:
52 case GL_PROGRAM_INPUT:
53 case GL_PROGRAM_OUTPUT:
54 return true;
55 default:
56 return false;
57 }
58}
59
jchen10880683b2017-04-12 16:21:55 +080060bool ValidateProgramInterface(GLenum programInterface)
61{
62 return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
63 ValidateNamedProgramInterface(programInterface));
64}
65
Jiawei Shaoc6f82872018-04-24 14:14:50 +080066bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
jchen10880683b2017-04-12 16:21:55 +080067{
Jiawei Shaoc6f82872018-04-24 14:14:50 +080068 ASSERT(context);
jchen10880683b2017-04-12 16:21:55 +080069 switch (prop)
70 {
71 case GL_ACTIVE_VARIABLES:
72 case GL_BUFFER_BINDING:
73 case GL_NUM_ACTIVE_VARIABLES:
74
75 case GL_ARRAY_SIZE:
76
77 case GL_ARRAY_STRIDE:
78 case GL_BLOCK_INDEX:
79 case GL_IS_ROW_MAJOR:
80 case GL_MATRIX_STRIDE:
81
82 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
83
84 case GL_BUFFER_DATA_SIZE:
85
86 case GL_LOCATION:
87
88 case GL_NAME_LENGTH:
89
90 case GL_OFFSET:
91
92 case GL_REFERENCED_BY_VERTEX_SHADER:
93 case GL_REFERENCED_BY_FRAGMENT_SHADER:
94 case GL_REFERENCED_BY_COMPUTE_SHADER:
95
96 case GL_TOP_LEVEL_ARRAY_SIZE:
97 case GL_TOP_LEVEL_ARRAY_STRIDE:
98
99 case GL_TYPE:
100 return true;
101
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800102 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
103 return context->getExtensions().geometryShader;
104
Olli Etuaho0ca09752018-09-24 11:00:50 +0300105 case GL_LOCATION_INDEX_EXT:
106 return context->getExtensions().blendFuncExtended;
107
jchen10880683b2017-04-12 16:21:55 +0800108 default:
109 return false;
110 }
111}
112
113// GLES 3.10 spec: Page 82 -- Table 7.2
114bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
115{
116 switch (prop)
117 {
118 case GL_ACTIVE_VARIABLES:
119 case GL_BUFFER_BINDING:
120 case GL_NUM_ACTIVE_VARIABLES:
121 {
122 switch (programInterface)
123 {
124 case GL_ATOMIC_COUNTER_BUFFER:
125 case GL_SHADER_STORAGE_BLOCK:
126 case GL_UNIFORM_BLOCK:
127 return true;
128 default:
129 return false;
130 }
131 }
132
133 case GL_ARRAY_SIZE:
134 {
135 switch (programInterface)
136 {
137 case GL_BUFFER_VARIABLE:
138 case GL_PROGRAM_INPUT:
139 case GL_PROGRAM_OUTPUT:
140 case GL_TRANSFORM_FEEDBACK_VARYING:
141 case GL_UNIFORM:
142 return true;
143 default:
144 return false;
145 }
146 }
147
148 case GL_ARRAY_STRIDE:
149 case GL_BLOCK_INDEX:
150 case GL_IS_ROW_MAJOR:
151 case GL_MATRIX_STRIDE:
152 {
153 switch (programInterface)
154 {
155 case GL_BUFFER_VARIABLE:
156 case GL_UNIFORM:
157 return true;
158 default:
159 return false;
160 }
161 }
162
163 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
164 {
165 if (programInterface == GL_UNIFORM)
166 {
167 return true;
168 }
169 return false;
170 }
171
172 case GL_BUFFER_DATA_SIZE:
173 {
174 switch (programInterface)
175 {
176 case GL_ATOMIC_COUNTER_BUFFER:
177 case GL_SHADER_STORAGE_BLOCK:
178 case GL_UNIFORM_BLOCK:
179 return true;
180 default:
181 return false;
182 }
183 }
184
185 case GL_LOCATION:
186 {
187 return ValidateLocationProgramInterface(programInterface);
188 }
189
Olli Etuaho0ca09752018-09-24 11:00:50 +0300190 case GL_LOCATION_INDEX_EXT:
191 {
192 // EXT_blend_func_extended
193 return (programInterface == GL_PROGRAM_OUTPUT);
194 }
195
jchen10880683b2017-04-12 16:21:55 +0800196 case GL_NAME_LENGTH:
197 {
198 return ValidateNamedProgramInterface(programInterface);
199 }
200
201 case GL_OFFSET:
202 {
203 switch (programInterface)
204 {
205 case GL_BUFFER_VARIABLE:
206 case GL_UNIFORM:
207 return true;
208 default:
209 return false;
210 }
211 }
212
213 case GL_REFERENCED_BY_VERTEX_SHADER:
214 case GL_REFERENCED_BY_FRAGMENT_SHADER:
215 case GL_REFERENCED_BY_COMPUTE_SHADER:
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800216 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
jchen10880683b2017-04-12 16:21:55 +0800217 {
218 switch (programInterface)
219 {
220 case GL_ATOMIC_COUNTER_BUFFER:
221 case GL_BUFFER_VARIABLE:
222 case GL_PROGRAM_INPUT:
223 case GL_PROGRAM_OUTPUT:
224 case GL_SHADER_STORAGE_BLOCK:
225 case GL_UNIFORM:
226 case GL_UNIFORM_BLOCK:
227 return true;
228 default:
229 return false;
230 }
231 }
232
233 case GL_TOP_LEVEL_ARRAY_SIZE:
234 case GL_TOP_LEVEL_ARRAY_STRIDE:
235 {
236 if (programInterface == GL_BUFFER_VARIABLE)
237 {
238 return true;
239 }
240 return false;
241 }
242
243 case GL_TYPE:
244 {
245 switch (programInterface)
246 {
247 case GL_BUFFER_VARIABLE:
248 case GL_PROGRAM_INPUT:
249 case GL_PROGRAM_OUTPUT:
250 case GL_TRANSFORM_FEEDBACK_VARYING:
251 case GL_UNIFORM:
252 return true;
253 default:
254 return false;
255 }
256 }
257
258 default:
259 return false;
260 }
261}
262
jchen10fd7c3b52017-03-21 15:36:03 +0800263bool ValidateProgramResourceIndex(const Program *programObject,
264 GLenum programInterface,
265 GLuint index)
266{
267 switch (programInterface)
268 {
269 case GL_PROGRAM_INPUT:
270 return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
271
272 case GL_PROGRAM_OUTPUT:
273 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
274
jchen10fd7c3b52017-03-21 15:36:03 +0800275 case GL_UNIFORM:
jchen10baf5d942017-08-28 20:45:48 +0800276 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
277
Jiajia Qin3a9090f2017-09-27 14:37:04 +0800278 case GL_BUFFER_VARIABLE:
279 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
280
281 case GL_SHADER_STORAGE_BLOCK:
282 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
283
jchen10fd7c3b52017-03-21 15:36:03 +0800284 case GL_UNIFORM_BLOCK:
jchen1058f67be2017-10-27 08:59:27 +0800285 return (index < programObject->getActiveUniformBlockCount());
286
287 case GL_ATOMIC_COUNTER_BUFFER:
288 return (index < programObject->getActiveAtomicCounterBufferCount());
289
jchen10fd7c3b52017-03-21 15:36:03 +0800290 case GL_TRANSFORM_FEEDBACK_VARYING:
jchen10910a3da2017-11-15 09:40:11 +0800291 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
jchen10fd7c3b52017-03-21 15:36:03 +0800292
293 default:
294 UNREACHABLE();
295 return false;
296 }
297}
298
Jamie Madill5b772312018-03-08 20:28:32 -0500299bool ValidateProgramUniform(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800300 GLenum valueType,
301 GLuint program,
302 GLint location,
303 GLsizei count)
304{
305 // Check for ES31 program uniform entry points
306 if (context->getClientVersion() < Version(3, 1))
307 {
Jamie Madille0472f32018-11-27 16:32:45 -0500308 context->validationError(GL_INVALID_OPERATION, kES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800309 return false;
310 }
311
312 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500313 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800314 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
315 ValidateUniformValue(context, valueType, uniform->type);
316}
317
Jamie Madill5b772312018-03-08 20:28:32 -0500318bool ValidateProgramUniformMatrix(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800319 GLenum valueType,
320 GLuint program,
321 GLint location,
322 GLsizei count,
323 GLboolean transpose)
324{
325 // Check for ES31 program uniform entry points
326 if (context->getClientVersion() < Version(3, 1))
327 {
Jamie Madille0472f32018-11-27 16:32:45 -0500328 context->validationError(GL_INVALID_OPERATION, kES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800329 return false;
330 }
331
332 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500333 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800334 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
335 ValidateUniformMatrixValue(context, valueType, uniform->type);
336}
337
Jamie Madill5b772312018-03-08 20:28:32 -0500338bool ValidateVertexAttribFormatCommon(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800339 GLuint attribIndex,
340 GLint size,
341 GLenum type,
342 GLuint relativeOffset,
343 GLboolean pureInteger)
344{
345 if (context->getClientVersion() < ES_3_1)
346 {
Jamie Madille0472f32018-11-27 16:32:45 -0500347 context->validationError(GL_INVALID_OPERATION, kES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800348 return false;
349 }
350
351 const Caps &caps = context->getCaps();
352 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
353 {
Jamie Madille0472f32018-11-27 16:32:45 -0500354 context->validationError(GL_INVALID_VALUE, kRelativeOffsetTooLarge);
Jiajia Qin5451d532017-11-16 17:16:34 +0800355 return false;
356 }
357
358 // [OpenGL ES 3.1] Section 10.3.1 page 243:
359 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
360 if (context->getGLState().getVertexArrayId() == 0)
361 {
Jamie Madille0472f32018-11-27 16:32:45 -0500362 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
Jiajia Qin5451d532017-11-16 17:16:34 +0800363 return false;
364 }
365
366 return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
367}
368
jchen1015015f72017-03-16 13:54:21 +0800369} // anonymous namespace
370
Martin Radev66fb8202016-07-28 11:45:20 +0300371bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
372{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400373 if (context->getClientVersion() < ES_3_1)
Martin Radev66fb8202016-07-28 11:45:20 +0300374 {
Jamie Madille0472f32018-11-27 16:32:45 -0500375 context->validationError(GL_INVALID_OPERATION, kES31Required);
Martin Radev66fb8202016-07-28 11:45:20 +0300376 return false;
377 }
378
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400379 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
380 {
381 return false;
382 }
383
384 return true;
385}
386
387bool ValidateGetBooleani_vRobustANGLE(Context *context,
388 GLenum target,
389 GLuint index,
390 GLsizei bufSize,
391 GLsizei *length,
392 GLboolean *data)
393{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400394 if (context->getClientVersion() < ES_3_1)
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400395 {
Jamie Madille0472f32018-11-27 16:32:45 -0500396 context->validationError(GL_INVALID_OPERATION, kES31Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400397 return false;
398 }
399
400 if (!ValidateRobustEntryPoint(context, bufSize))
401 {
402 return false;
403 }
404
Brandon Jonesd1049182018-03-28 10:02:20 -0700405 GLsizei numParams = 0;
406
407 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400408 {
409 return false;
410 }
411
Brandon Jonesd1049182018-03-28 10:02:20 -0700412 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Martin Radev66fb8202016-07-28 11:45:20 +0300413 {
414 return false;
415 }
416
Brandon Jonesd1049182018-03-28 10:02:20 -0700417 SetRobustLengthParam(length, numParams);
Martin Radev66fb8202016-07-28 11:45:20 +0300418 return true;
419}
420
Jamie Madill493f9572018-05-24 19:52:15 -0400421bool ValidateDrawIndirectBase(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800422{
423 if (context->getClientVersion() < ES_3_1)
424 {
Jamie Madille0472f32018-11-27 16:32:45 -0500425 context->validationError(GL_INVALID_OPERATION, kES31Required);
Jiajia Qind9671222016-11-29 16:30:31 +0800426 return false;
427 }
428
429 // Here the third parameter 1 is only to pass the count validation.
430 if (!ValidateDrawBase(context, mode, 1))
431 {
432 return false;
433 }
434
435 const State &state = context->getGLState();
436
437 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
438 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
439 if (!state.getVertexArrayId())
440 {
Jamie Madille0472f32018-11-27 16:32:45 -0500441 context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
Jiajia Qind9671222016-11-29 16:30:31 +0800442 return false;
443 }
444
Jamie Madill5b772312018-03-08 20:28:32 -0500445 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800446 if (!drawIndirectBuffer)
447 {
Jamie Madille0472f32018-11-27 16:32:45 -0500448 context->validationError(GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
Jiajia Qind9671222016-11-29 16:30:31 +0800449 return false;
450 }
451
452 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
453 // machine units, of uint.
454 GLint64 offset = reinterpret_cast<GLint64>(indirect);
455 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
456 {
Jamie Madille0472f32018-11-27 16:32:45 -0500457 context->validationError(GL_INVALID_VALUE, kInvalidIndirectOffset);
Jiajia Qind9671222016-11-29 16:30:31 +0800458 return false;
459 }
460
Martin Radev14a26ae2017-07-24 15:56:29 +0300461 // ANGLE_multiview spec, revision 1:
462 // An INVALID_OPERATION is generated by DrawArraysIndirect and DrawElementsIndirect if the
463 // number of views in the draw framebuffer is greater than 1.
464 const Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
465 ASSERT(drawFramebuffer != nullptr);
466 if (drawFramebuffer->getNumViews() > 1)
467 {
Jamie Madille0472f32018-11-27 16:32:45 -0500468 context->validationError(GL_INVALID_OPERATION, kMultiviewActive);
Martin Radev14a26ae2017-07-24 15:56:29 +0300469 return false;
470 }
471
Jiajia Qind9671222016-11-29 16:30:31 +0800472 return true;
473}
474
Jamie Madill493f9572018-05-24 19:52:15 -0400475bool ValidateDrawArraysIndirect(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800476{
Jamie Madill493f9572018-05-24 19:52:15 -0400477 const State &state = context->getGLState();
478 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
Jiajia Qind9671222016-11-29 16:30:31 +0800479 if (curTransformFeedback && curTransformFeedback->isActive() &&
480 !curTransformFeedback->isPaused())
481 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800482 // EXT_geometry_shader allows transform feedback to work with all draw commands.
483 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
484 if (context->getExtensions().geometryShader)
485 {
486 if (!ValidateTransformFeedbackPrimitiveMode(
487 context, curTransformFeedback->getPrimitiveMode(), mode))
488 {
Jamie Madille0472f32018-11-27 16:32:45 -0500489 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800490 return false;
491 }
492 }
493 else
494 {
495 // An INVALID_OPERATION error is generated if transform feedback is active and not
496 // paused.
Jamie Madill610640f2018-11-21 17:28:41 -0500497 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -0500498 kUnsupportedDrawModeForTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800499 return false;
500 }
Jiajia Qind9671222016-11-29 16:30:31 +0800501 }
502
503 if (!ValidateDrawIndirectBase(context, mode, indirect))
504 return false;
505
Jamie Madill5b772312018-03-08 20:28:32 -0500506 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800507 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
508 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
509 // which's size is 4 * sizeof(uint).
510 auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
511 if (!checkedSum.IsValid() ||
512 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
513 {
Jamie Madille0472f32018-11-27 16:32:45 -0500514 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jiajia Qind9671222016-11-29 16:30:31 +0800515 return false;
516 }
517
518 return true;
519}
520
Jamie Madill493f9572018-05-24 19:52:15 -0400521bool ValidateDrawElementsIndirect(Context *context,
522 PrimitiveMode mode,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500523 DrawElementsType type,
Jamie Madill493f9572018-05-24 19:52:15 -0400524 const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800525{
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800526 if (!ValidateDrawElementsBase(context, mode, type))
527 {
Jiajia Qind9671222016-11-29 16:30:31 +0800528 return false;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800529 }
Jiajia Qind9671222016-11-29 16:30:31 +0800530
Jamie Madill493f9572018-05-24 19:52:15 -0400531 const State &state = context->getGLState();
532 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400533 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jiajia Qind9671222016-11-29 16:30:31 +0800534 if (!elementArrayBuffer)
535 {
Jamie Madille0472f32018-11-27 16:32:45 -0500536 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
Jiajia Qind9671222016-11-29 16:30:31 +0800537 return false;
538 }
539
540 if (!ValidateDrawIndirectBase(context, mode, indirect))
541 return false;
542
Jamie Madill5b772312018-03-08 20:28:32 -0500543 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800544 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
545 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
546 // which's size is 5 * sizeof(uint).
547 auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
548 if (!checkedSum.IsValid() ||
549 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
550 {
Jamie Madill610640f2018-11-21 17:28:41 -0500551 context->validationError(
552 GL_INVALID_OPERATION,
553 "the command would source data beyond the end of the buffer object.");
Jiajia Qind9671222016-11-29 16:30:31 +0800554 return false;
555 }
556
557 return true;
558}
559
Jiajia Qin5451d532017-11-16 17:16:34 +0800560bool ValidateProgramUniform1i(Context *context, GLuint program, GLint location, GLint v0)
561{
562 return ValidateProgramUniform1iv(context, program, location, 1, &v0);
563}
564
565bool ValidateProgramUniform2i(Context *context, GLuint program, GLint location, GLint v0, GLint v1)
566{
567 GLint xy[2] = {v0, v1};
568 return ValidateProgramUniform2iv(context, program, location, 1, xy);
569}
570
571bool ValidateProgramUniform3i(Context *context,
572 GLuint program,
573 GLint location,
574 GLint v0,
575 GLint v1,
576 GLint v2)
577{
578 GLint xyz[3] = {v0, v1, v2};
579 return ValidateProgramUniform3iv(context, program, location, 1, xyz);
580}
581
582bool ValidateProgramUniform4i(Context *context,
583 GLuint program,
584 GLint location,
585 GLint v0,
586 GLint v1,
587 GLint v2,
588 GLint v3)
589{
590 GLint xyzw[4] = {v0, v1, v2, v3};
591 return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
592}
593
594bool ValidateProgramUniform1ui(Context *context, GLuint program, GLint location, GLuint v0)
595{
596 return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
597}
598
599bool ValidateProgramUniform2ui(Context *context,
600 GLuint program,
601 GLint location,
602 GLuint v0,
603 GLuint v1)
604{
605 GLuint xy[2] = {v0, v1};
606 return ValidateProgramUniform2uiv(context, program, location, 1, xy);
607}
608
609bool ValidateProgramUniform3ui(Context *context,
610 GLuint program,
611 GLint location,
612 GLuint v0,
613 GLuint v1,
614 GLuint v2)
615{
616 GLuint xyz[3] = {v0, v1, v2};
617 return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
618}
619
620bool ValidateProgramUniform4ui(Context *context,
621 GLuint program,
622 GLint location,
623 GLuint v0,
624 GLuint v1,
625 GLuint v2,
626 GLuint v3)
627{
628 GLuint xyzw[4] = {v0, v1, v2, v3};
629 return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
630}
631
632bool ValidateProgramUniform1f(Context *context, GLuint program, GLint location, GLfloat v0)
633{
634 return ValidateProgramUniform1fv(context, program, location, 1, &v0);
635}
636
637bool ValidateProgramUniform2f(Context *context,
638 GLuint program,
639 GLint location,
640 GLfloat v0,
641 GLfloat v1)
642{
643 GLfloat xy[2] = {v0, v1};
644 return ValidateProgramUniform2fv(context, program, location, 1, xy);
645}
646
647bool ValidateProgramUniform3f(Context *context,
648 GLuint program,
649 GLint location,
650 GLfloat v0,
651 GLfloat v1,
652 GLfloat v2)
653{
654 GLfloat xyz[3] = {v0, v1, v2};
655 return ValidateProgramUniform3fv(context, program, location, 1, xyz);
656}
657
658bool ValidateProgramUniform4f(Context *context,
659 GLuint program,
660 GLint location,
661 GLfloat v0,
662 GLfloat v1,
663 GLfloat v2,
664 GLfloat v3)
665{
666 GLfloat xyzw[4] = {v0, v1, v2, v3};
667 return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
668}
669
670bool ValidateProgramUniform1iv(Context *context,
671 GLuint program,
672 GLint location,
673 GLsizei count,
674 const GLint *value)
675{
676 // Check for ES31 program uniform entry points
677 if (context->getClientVersion() < Version(3, 1))
678 {
Jamie Madille0472f32018-11-27 16:32:45 -0500679 context->validationError(GL_INVALID_OPERATION, kES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800680 return false;
681 }
682
683 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500684 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800685 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
686 ValidateUniform1ivValue(context, uniform->type, count, value);
687}
688
689bool ValidateProgramUniform2iv(Context *context,
690 GLuint program,
691 GLint location,
692 GLsizei count,
693 const GLint *value)
694{
695 return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
696}
697
698bool ValidateProgramUniform3iv(Context *context,
699 GLuint program,
700 GLint location,
701 GLsizei count,
702 const GLint *value)
703{
704 return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
705}
706
707bool ValidateProgramUniform4iv(Context *context,
708 GLuint program,
709 GLint location,
710 GLsizei count,
711 const GLint *value)
712{
713 return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
714}
715
716bool ValidateProgramUniform1uiv(Context *context,
717 GLuint program,
718 GLint location,
719 GLsizei count,
720 const GLuint *value)
721{
722 return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
723}
724
725bool ValidateProgramUniform2uiv(Context *context,
726 GLuint program,
727 GLint location,
728 GLsizei count,
729 const GLuint *value)
730{
731 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
732}
733
734bool ValidateProgramUniform3uiv(Context *context,
735 GLuint program,
736 GLint location,
737 GLsizei count,
738 const GLuint *value)
739{
740 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
741}
742
743bool ValidateProgramUniform4uiv(Context *context,
744 GLuint program,
745 GLint location,
746 GLsizei count,
747 const GLuint *value)
748{
749 return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
750}
751
752bool ValidateProgramUniform1fv(Context *context,
753 GLuint program,
754 GLint location,
755 GLsizei count,
756 const GLfloat *value)
757{
758 return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
759}
760
761bool ValidateProgramUniform2fv(Context *context,
762 GLuint program,
763 GLint location,
764 GLsizei count,
765 const GLfloat *value)
766{
767 return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
768}
769
770bool ValidateProgramUniform3fv(Context *context,
771 GLuint program,
772 GLint location,
773 GLsizei count,
774 const GLfloat *value)
775{
776 return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
777}
778
779bool ValidateProgramUniform4fv(Context *context,
780 GLuint program,
781 GLint location,
782 GLsizei count,
783 const GLfloat *value)
784{
785 return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
786}
787
788bool ValidateProgramUniformMatrix2fv(Context *context,
789 GLuint program,
790 GLint location,
791 GLsizei count,
792 GLboolean transpose,
793 const GLfloat *value)
794{
795 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
796 transpose);
797}
798
799bool ValidateProgramUniformMatrix3fv(Context *context,
800 GLuint program,
801 GLint location,
802 GLsizei count,
803 GLboolean transpose,
804 const GLfloat *value)
805{
806 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
807 transpose);
808}
809
810bool ValidateProgramUniformMatrix4fv(Context *context,
811 GLuint program,
812 GLint location,
813 GLsizei count,
814 GLboolean transpose,
815 const GLfloat *value)
816{
817 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
818 transpose);
819}
820
821bool ValidateProgramUniformMatrix2x3fv(Context *context,
822 GLuint program,
823 GLint location,
824 GLsizei count,
825 GLboolean transpose,
826 const GLfloat *value)
827{
828 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
829 transpose);
830}
831
832bool ValidateProgramUniformMatrix3x2fv(Context *context,
833 GLuint program,
834 GLint location,
835 GLsizei count,
836 GLboolean transpose,
837 const GLfloat *value)
838{
839 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
840 transpose);
841}
842
843bool ValidateProgramUniformMatrix2x4fv(Context *context,
844 GLuint program,
845 GLint location,
846 GLsizei count,
847 GLboolean transpose,
848 const GLfloat *value)
849{
850 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
851 transpose);
852}
853
854bool ValidateProgramUniformMatrix4x2fv(Context *context,
855 GLuint program,
856 GLint location,
857 GLsizei count,
858 GLboolean transpose,
859 const GLfloat *value)
860{
861 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
862 transpose);
863}
864
865bool ValidateProgramUniformMatrix3x4fv(Context *context,
866 GLuint program,
867 GLint location,
868 GLsizei count,
869 GLboolean transpose,
870 const GLfloat *value)
871{
872 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
873 transpose);
874}
875
876bool ValidateProgramUniformMatrix4x3fv(Context *context,
877 GLuint program,
878 GLint location,
879 GLsizei count,
880 GLboolean transpose,
881 const GLfloat *value)
882{
883 return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
884 transpose);
885}
886
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800887bool ValidateGetTexLevelParameterfv(Context *context,
888 TextureTarget target,
889 GLint level,
890 GLenum pname,
891 GLfloat *params)
He Yunchao11b038b2016-11-22 21:24:04 +0800892{
893 if (context->getClientVersion() < ES_3_1)
894 {
Jamie Madille0472f32018-11-27 16:32:45 -0500895 context->validationError(GL_INVALID_OPERATION, kES31Required);
He Yunchao11b038b2016-11-22 21:24:04 +0800896 return false;
897 }
898
He Yunchao11b038b2016-11-22 21:24:04 +0800899 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
900}
901
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700902bool ValidateGetTexLevelParameterfvRobustANGLE(Context *context,
903 TextureTarget target,
904 GLint level,
905 GLenum pname,
906 GLsizei bufSize,
907 GLsizei *length,
908 GLfloat *params)
909{
910 UNIMPLEMENTED();
911 return false;
912}
913
He Yunchao11b038b2016-11-22 21:24:04 +0800914bool ValidateGetTexLevelParameteriv(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800915 TextureTarget target,
He Yunchao11b038b2016-11-22 21:24:04 +0800916 GLint level,
917 GLenum pname,
918 GLint *params)
919{
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800920 if (context->getClientVersion() < ES_3_1)
921 {
Jamie Madille0472f32018-11-27 16:32:45 -0500922 context->validationError(GL_INVALID_OPERATION, kES31Required);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +0800923 return false;
924 }
925
He Yunchao11b038b2016-11-22 21:24:04 +0800926 return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
927}
928
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700929bool ValidateGetTexLevelParameterivRobustANGLE(Context *context,
930 TextureTarget target,
931 GLint level,
932 GLenum pname,
933 GLsizei bufSize,
934 GLsizei *length,
935 GLint *params)
936{
937 UNIMPLEMENTED();
938 return false;
939}
940
Jiajia Qin5451d532017-11-16 17:16:34 +0800941bool ValidateTexStorage2DMultisample(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800942 TextureType target,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800943 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -0500944 GLenum internalFormat,
JiangYizhoubddc46b2016-12-09 09:50:51 +0800945 GLsizei width,
946 GLsizei height,
947 GLboolean fixedSampleLocations)
948{
949 if (context->getClientVersion() < ES_3_1)
950 {
Jamie Madille0472f32018-11-27 16:32:45 -0500951 context->validationError(GL_INVALID_OPERATION, kES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800952 return false;
953 }
954
Yizhou Jiang7818a852018-09-06 15:02:04 +0800955 return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
956 height);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800957}
958
959bool ValidateGetMultisamplefv(Context *context, GLenum pname, GLuint index, GLfloat *val)
960{
961 if (context->getClientVersion() < ES_3_1)
962 {
Jamie Madille0472f32018-11-27 16:32:45 -0500963 context->validationError(GL_INVALID_OPERATION, kES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800964 return false;
965 }
966
Yizhou Jiang7310da32018-11-05 14:40:01 +0800967 return ValidateGetMultisamplefvBase(context, pname, index, val);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800968}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800969
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700970bool ValidateGetMultisamplefvRobustANGLE(Context *context,
971 GLenum pname,
972 GLuint index,
973 GLsizei bufSize,
974 GLsizei *length,
975 GLfloat *val)
976{
977 UNIMPLEMENTED();
978 return false;
979}
980
Jiajia Qin5451d532017-11-16 17:16:34 +0800981bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800982{
983 if (context->getClientVersion() < ES_3_1)
984 {
Jamie Madille0472f32018-11-27 16:32:45 -0500985 context->validationError(GL_INVALID_OPERATION, kES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800986 return false;
987 }
988
Geoff Lange8afa902017-09-27 15:00:43 -0400989 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800990 {
Jamie Madille0472f32018-11-27 16:32:45 -0500991 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800992 return false;
993 }
994
995 switch (pname)
996 {
997 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
998 {
999 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1000 if (param < 0 || param > maxWidth)
1001 {
Jamie Madill610640f2018-11-21 17:28:41 -05001002 context->validationError(
1003 GL_INVALID_VALUE,
1004 "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001005 return false;
1006 }
1007 break;
1008 }
1009 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1010 {
1011 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1012 if (param < 0 || param > maxHeight)
1013 {
Jamie Madill610640f2018-11-21 17:28:41 -05001014 context->validationError(
1015 GL_INVALID_VALUE,
1016 "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001017 return false;
1018 }
1019 break;
1020 }
1021 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1022 {
1023 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1024 if (param < 0 || param > maxSamples)
1025 {
Jamie Madill610640f2018-11-21 17:28:41 -05001026 context->validationError(
1027 GL_INVALID_VALUE,
1028 "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001029 return false;
1030 }
1031 break;
1032 }
1033 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1034 {
1035 break;
1036 }
Jiawei Shaob1e91382018-05-17 14:33:55 +08001037 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1038 {
1039 if (!context->getExtensions().geometryShader)
1040 {
Jamie Madille0472f32018-11-27 16:32:45 -05001041 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaob1e91382018-05-17 14:33:55 +08001042 return false;
1043 }
1044 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1045 if (param < 0 || param > maxLayers)
1046 {
Jamie Madille0472f32018-11-27 16:32:45 -05001047 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferLayer);
Jiawei Shaob1e91382018-05-17 14:33:55 +08001048 return false;
1049 }
1050 break;
1051 }
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001052 default:
1053 {
Jamie Madille0472f32018-11-27 16:32:45 -05001054 context->validationError(GL_INVALID_ENUM, kInvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001055 return false;
1056 }
1057 }
1058
1059 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1060 ASSERT(framebuffer);
1061 if (framebuffer->id() == 0)
1062 {
Jamie Madill610640f2018-11-21 17:28:41 -05001063 context->validationError(GL_INVALID_OPERATION, "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001064 return false;
1065 }
1066 return true;
1067}
1068
Jiajia Qin5451d532017-11-16 17:16:34 +08001069bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001070{
1071 if (context->getClientVersion() < ES_3_1)
1072 {
Jamie Madille0472f32018-11-27 16:32:45 -05001073 context->validationError(GL_INVALID_OPERATION, kES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001074 return false;
1075 }
1076
Geoff Lange8afa902017-09-27 15:00:43 -04001077 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001078 {
Jamie Madille0472f32018-11-27 16:32:45 -05001079 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001080 return false;
1081 }
1082
1083 switch (pname)
1084 {
1085 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1086 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1087 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1088 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1089 break;
Jiawei Shaob1e91382018-05-17 14:33:55 +08001090 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1091 if (!context->getExtensions().geometryShader)
1092 {
Jamie Madille0472f32018-11-27 16:32:45 -05001093 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaob1e91382018-05-17 14:33:55 +08001094 return false;
1095 }
1096 break;
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001097 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001098 context->validationError(GL_INVALID_ENUM, kInvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001099 return false;
1100 }
1101
1102 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1103 ASSERT(framebuffer);
1104
1105 if (framebuffer->id() == 0)
1106 {
Jamie Madill610640f2018-11-21 17:28:41 -05001107 context->validationError(GL_INVALID_OPERATION, "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001108 return false;
1109 }
1110 return true;
1111}
1112
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001113bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1114 GLenum target,
1115 GLenum pname,
1116 GLsizei bufSize,
1117 GLsizei *length,
1118 GLint *params)
1119{
1120 UNIMPLEMENTED();
1121 return false;
1122}
1123
jchen1015015f72017-03-16 13:54:21 +08001124bool ValidateGetProgramResourceIndex(Context *context,
1125 GLuint program,
1126 GLenum programInterface,
1127 const GLchar *name)
1128{
1129 if (context->getClientVersion() < ES_3_1)
1130 {
Jamie Madille0472f32018-11-27 16:32:45 -05001131 context->validationError(GL_INVALID_OPERATION, kES31Required);
jchen1015015f72017-03-16 13:54:21 +08001132 return false;
1133 }
1134
1135 Program *programObject = GetValidProgram(context, program);
1136 if (programObject == nullptr)
1137 {
1138 return false;
1139 }
1140
1141 if (!ValidateNamedProgramInterface(programInterface))
1142 {
Jamie Madill610640f2018-11-21 17:28:41 -05001143 context->validationError(GL_INVALID_ENUM, "Invalid program interface");
jchen1015015f72017-03-16 13:54:21 +08001144 return false;
1145 }
Shao80957d92017-02-20 21:25:59 +08001146
1147 return true;
1148}
1149
Jamie Madill5b772312018-03-08 20:28:32 -05001150bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001151 GLuint bindingIndex,
1152 GLuint buffer,
1153 GLintptr offset,
1154 GLsizei stride)
1155{
1156 if (context->getClientVersion() < ES_3_1)
1157 {
Jamie Madille0472f32018-11-27 16:32:45 -05001158 context->validationError(GL_INVALID_OPERATION, kES31Required);
Shao80957d92017-02-20 21:25:59 +08001159 return false;
1160 }
1161
1162 if (!context->isBufferGenerated(buffer))
1163 {
Jamie Madill610640f2018-11-21 17:28:41 -05001164 context->validationError(GL_INVALID_OPERATION, "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001165 return false;
1166 }
1167
1168 const Caps &caps = context->getCaps();
1169 if (bindingIndex >= caps.maxVertexAttribBindings)
1170 {
Jamie Madill610640f2018-11-21 17:28:41 -05001171 context->validationError(GL_INVALID_VALUE,
1172 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001173 return false;
1174 }
1175
1176 if (offset < 0)
1177 {
Jamie Madille0472f32018-11-27 16:32:45 -05001178 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001179 return false;
1180 }
1181
1182 if (stride < 0 || stride > caps.maxVertexAttribStride)
1183 {
Jamie Madill610640f2018-11-21 17:28:41 -05001184 context->validationError(GL_INVALID_VALUE,
1185 "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001186 return false;
1187 }
1188
1189 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1190 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1191 if (context->getGLState().getVertexArrayId() == 0)
1192 {
Jamie Madill610640f2018-11-21 17:28:41 -05001193 context->validationError(GL_INVALID_OPERATION, "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001194 return false;
1195 }
1196
1197 return true;
1198}
1199
Jamie Madill5b772312018-03-08 20:28:32 -05001200bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001201{
1202 if (context->getClientVersion() < ES_3_1)
1203 {
Jamie Madille0472f32018-11-27 16:32:45 -05001204 context->validationError(GL_INVALID_OPERATION, kES31Required);
Shao80957d92017-02-20 21:25:59 +08001205 return false;
1206 }
1207
1208 const Caps &caps = context->getCaps();
1209 if (bindingIndex >= caps.maxVertexAttribBindings)
1210 {
Jamie Madill610640f2018-11-21 17:28:41 -05001211 context->validationError(GL_INVALID_VALUE,
1212 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001213 return false;
1214 }
1215
1216 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1217 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1218 if (context->getGLState().getVertexArrayId() == 0)
1219 {
Jamie Madill610640f2018-11-21 17:28:41 -05001220 context->validationError(GL_INVALID_OPERATION, "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001221 return false;
1222 }
1223
1224 return true;
1225}
1226
Jamie Madill5b772312018-03-08 20:28:32 -05001227bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001228 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001229 GLint size,
1230 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001231 GLboolean normalized,
1232 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001233{
Jiajia Qin5451d532017-11-16 17:16:34 +08001234 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1235 false);
1236}
Shao80957d92017-02-20 21:25:59 +08001237
Jamie Madill5b772312018-03-08 20:28:32 -05001238bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001239 GLuint attribindex,
1240 GLint size,
1241 GLenum type,
1242 GLuint relativeoffset)
1243{
1244 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001245}
1246
Jamie Madill5b772312018-03-08 20:28:32 -05001247bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001248{
1249 if (context->getClientVersion() < ES_3_1)
1250 {
Jamie Madille0472f32018-11-27 16:32:45 -05001251 context->validationError(GL_INVALID_OPERATION, kES31Required);
Shao80957d92017-02-20 21:25:59 +08001252 return false;
1253 }
1254
1255 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1256 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1257 if (context->getGLState().getVertexArrayId() == 0)
1258 {
Jamie Madill610640f2018-11-21 17:28:41 -05001259 context->validationError(GL_INVALID_OPERATION, "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001260 return false;
1261 }
1262
1263 const Caps &caps = context->getCaps();
1264 if (attribIndex >= caps.maxVertexAttributes)
1265 {
Jamie Madille0472f32018-11-27 16:32:45 -05001266 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001267 return false;
1268 }
1269
1270 if (bindingIndex >= caps.maxVertexAttribBindings)
1271 {
Jamie Madill610640f2018-11-21 17:28:41 -05001272 context->validationError(GL_INVALID_VALUE,
1273 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001274 return false;
1275 }
1276
jchen1015015f72017-03-16 13:54:21 +08001277 return true;
1278}
1279
jchen10fd7c3b52017-03-21 15:36:03 +08001280bool ValidateGetProgramResourceName(Context *context,
1281 GLuint program,
1282 GLenum programInterface,
1283 GLuint index,
1284 GLsizei bufSize,
1285 GLsizei *length,
1286 GLchar *name)
1287{
1288 if (context->getClientVersion() < ES_3_1)
1289 {
Jamie Madille0472f32018-11-27 16:32:45 -05001290 context->validationError(GL_INVALID_OPERATION, kES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001291 return false;
1292 }
1293
1294 Program *programObject = GetValidProgram(context, program);
1295 if (programObject == nullptr)
1296 {
1297 return false;
1298 }
1299
1300 if (!ValidateNamedProgramInterface(programInterface))
1301 {
Jamie Madill610640f2018-11-21 17:28:41 -05001302 context->validationError(GL_INVALID_ENUM, "Invalid program interface");
jchen10fd7c3b52017-03-21 15:36:03 +08001303 return false;
1304 }
1305
1306 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1307 {
Jamie Madill610640f2018-11-21 17:28:41 -05001308 context->validationError(GL_INVALID_VALUE, "Invalid index");
jchen10fd7c3b52017-03-21 15:36:03 +08001309 return false;
1310 }
1311
1312 if (bufSize < 0)
1313 {
Jamie Madille0472f32018-11-27 16:32:45 -05001314 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001315 return false;
1316 }
1317
1318 return true;
1319}
1320
Xinghua Cao2b396592017-03-29 15:36:04 +08001321bool ValidateDispatchCompute(Context *context,
1322 GLuint numGroupsX,
1323 GLuint numGroupsY,
1324 GLuint numGroupsZ)
1325{
1326 if (context->getClientVersion() < ES_3_1)
1327 {
Jamie Madille0472f32018-11-27 16:32:45 -05001328 context->validationError(GL_INVALID_OPERATION, kES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001329 return false;
1330 }
1331
1332 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001333 Program *program = state.getLinkedProgram(context);
Xinghua Cao2b396592017-03-29 15:36:04 +08001334
Jiawei Shao385b3e02018-03-21 09:43:28 +08001335 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001336 {
Jamie Madille0472f32018-11-27 16:32:45 -05001337 context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001338 return false;
1339 }
1340
1341 const Caps &caps = context->getCaps();
1342 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1343 {
Jamie Madill610640f2018-11-21 17:28:41 -05001344 context->validationError(
1345 GL_INVALID_VALUE,
1346 "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]");
Xinghua Cao2b396592017-03-29 15:36:04 +08001347 return false;
1348 }
1349 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1350 {
Jamie Madill610640f2018-11-21 17:28:41 -05001351 context->validationError(
1352 GL_INVALID_VALUE,
1353 "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]");
Xinghua Cao2b396592017-03-29 15:36:04 +08001354 return false;
1355 }
1356 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1357 {
Jamie Madill610640f2018-11-21 17:28:41 -05001358 context->validationError(
1359 GL_INVALID_VALUE,
1360 "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]");
Xinghua Cao2b396592017-03-29 15:36:04 +08001361 return false;
1362 }
1363
1364 return true;
1365}
1366
Jiajia Qin5451d532017-11-16 17:16:34 +08001367bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1368{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001369 if (context->getClientVersion() < ES_3_1)
1370 {
Jamie Madille0472f32018-11-27 16:32:45 -05001371 context->validationError(GL_INVALID_OPERATION, kES31Required);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001372 return false;
1373 }
1374
1375 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001376 Program *program = state.getLinkedProgram(context);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001377
Jiawei Shao385b3e02018-03-21 09:43:28 +08001378 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001379 {
Jamie Madille0472f32018-11-27 16:32:45 -05001380 context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001381 return false;
1382 }
1383
Qin Jiajia62fcf622017-11-30 16:16:12 +08001384 if (indirect < 0)
1385 {
Jamie Madille0472f32018-11-27 16:32:45 -05001386 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001387 return false;
1388 }
1389
1390 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1391 {
Jamie Madille0472f32018-11-27 16:32:45 -05001392 context->validationError(GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001393 return false;
1394 }
1395
Jamie Madill5b772312018-03-08 20:28:32 -05001396 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001397 if (!dispatchIndirectBuffer)
1398 {
Jamie Madille0472f32018-11-27 16:32:45 -05001399 context->validationError(GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001400 return false;
1401 }
1402
1403 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1404 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1405 if (!checkedSum.IsValid() ||
1406 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1407 {
Jamie Madille0472f32018-11-27 16:32:45 -05001408 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001409 return false;
1410 }
1411
1412 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001413}
1414
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001415bool ValidateBindImageTexture(Context *context,
1416 GLuint unit,
1417 GLuint texture,
1418 GLint level,
1419 GLboolean layered,
1420 GLint layer,
1421 GLenum access,
1422 GLenum format)
1423{
1424 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1425 if (unit >= maxImageUnits)
1426 {
Jamie Madill610640f2018-11-21 17:28:41 -05001427 context->validationError(GL_INVALID_VALUE,
1428 "unit cannot be greater than or equal than MAX_IMAGE_UNITS");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001429 return false;
1430 }
1431
1432 if (level < 0)
1433 {
Jamie Madill610640f2018-11-21 17:28:41 -05001434 context->validationError(GL_INVALID_VALUE, "level is negative.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001435 return false;
1436 }
1437
1438 if (layer < 0)
1439 {
Jamie Madill610640f2018-11-21 17:28:41 -05001440 context->validationError(GL_INVALID_VALUE, "layer is negative.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001441 return false;
1442 }
1443
1444 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1445 {
Jamie Madill610640f2018-11-21 17:28:41 -05001446 context->validationError(GL_INVALID_ENUM, "access is not one of the supported tokens.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001447 return false;
1448 }
1449
1450 switch (format)
1451 {
1452 case GL_RGBA32F:
1453 case GL_RGBA16F:
1454 case GL_R32F:
1455 case GL_RGBA32UI:
1456 case GL_RGBA16UI:
1457 case GL_RGBA8UI:
1458 case GL_R32UI:
1459 case GL_RGBA32I:
1460 case GL_RGBA16I:
1461 case GL_RGBA8I:
1462 case GL_R32I:
1463 case GL_RGBA8:
1464 case GL_RGBA8_SNORM:
1465 break;
1466 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001467 context->validationError(GL_INVALID_VALUE,
1468 "format is not one of supported image unit formats.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001469 return false;
1470 }
1471
1472 if (texture != 0)
1473 {
1474 Texture *tex = context->getTexture(texture);
1475
1476 if (tex == nullptr)
1477 {
Jamie Madill610640f2018-11-21 17:28:41 -05001478 context->validationError(GL_INVALID_VALUE,
1479 "texture is not the name of an existing texture object.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001480 return false;
1481 }
1482
1483 if (!tex->getImmutableFormat())
1484 {
Jamie Madill610640f2018-11-21 17:28:41 -05001485 context->validationError(GL_INVALID_OPERATION,
1486 "texture is not the name of an immutable texture object.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001487 return false;
1488 }
1489 }
1490
1491 return true;
1492}
jchen10191381f2017-04-11 13:59:04 +08001493
1494bool ValidateGetProgramResourceLocation(Context *context,
1495 GLuint program,
1496 GLenum programInterface,
1497 const GLchar *name)
1498{
1499 if (context->getClientVersion() < ES_3_1)
1500 {
Jamie Madille0472f32018-11-27 16:32:45 -05001501 context->validationError(GL_INVALID_OPERATION, kES31Required);
jchen10191381f2017-04-11 13:59:04 +08001502 return false;
1503 }
1504
1505 Program *programObject = GetValidProgram(context, program);
1506 if (programObject == nullptr)
1507 {
1508 return false;
1509 }
1510
1511 if (!programObject->isLinked())
1512 {
Jamie Madill610640f2018-11-21 17:28:41 -05001513 context->validationError(GL_INVALID_OPERATION, "Program is not successfully linked.");
jchen10191381f2017-04-11 13:59:04 +08001514 return false;
1515 }
1516
1517 if (!ValidateLocationProgramInterface(programInterface))
1518 {
Jamie Madill610640f2018-11-21 17:28:41 -05001519 context->validationError(GL_INVALID_ENUM, "Invalid program interface.");
jchen10191381f2017-04-11 13:59:04 +08001520 return false;
1521 }
1522 return true;
1523}
1524
jchen10880683b2017-04-12 16:21:55 +08001525bool ValidateGetProgramResourceiv(Context *context,
1526 GLuint program,
1527 GLenum programInterface,
1528 GLuint index,
1529 GLsizei propCount,
1530 const GLenum *props,
1531 GLsizei bufSize,
1532 GLsizei *length,
1533 GLint *params)
1534{
1535 if (context->getClientVersion() < ES_3_1)
1536 {
Jamie Madille0472f32018-11-27 16:32:45 -05001537 context->validationError(GL_INVALID_OPERATION, kES31Required);
jchen10880683b2017-04-12 16:21:55 +08001538 return false;
1539 }
1540
1541 Program *programObject = GetValidProgram(context, program);
1542 if (programObject == nullptr)
1543 {
1544 return false;
1545 }
1546 if (!ValidateProgramInterface(programInterface))
1547 {
Jamie Madill610640f2018-11-21 17:28:41 -05001548 context->validationError(GL_INVALID_ENUM, "Invalid program interface.");
jchen10880683b2017-04-12 16:21:55 +08001549 return false;
1550 }
1551 if (propCount <= 0)
1552 {
Jamie Madill610640f2018-11-21 17:28:41 -05001553 context->validationError(GL_INVALID_VALUE, "Invalid propCount.");
jchen10880683b2017-04-12 16:21:55 +08001554 return false;
1555 }
1556 if (bufSize < 0)
1557 {
Jamie Madill610640f2018-11-21 17:28:41 -05001558 context->validationError(GL_INVALID_VALUE, "Invalid bufSize.");
jchen10880683b2017-04-12 16:21:55 +08001559 return false;
1560 }
1561 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1562 {
Jamie Madill610640f2018-11-21 17:28:41 -05001563 context->validationError(GL_INVALID_VALUE, "Invalid index");
jchen10880683b2017-04-12 16:21:55 +08001564 return false;
1565 }
1566 for (GLsizei i = 0; i < propCount; i++)
1567 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001568 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001569 {
Jamie Madill610640f2018-11-21 17:28:41 -05001570 context->validationError(GL_INVALID_ENUM, "Invalid prop.");
jchen10880683b2017-04-12 16:21:55 +08001571 return false;
1572 }
1573 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1574 {
Jamie Madill610640f2018-11-21 17:28:41 -05001575 context->validationError(GL_INVALID_OPERATION, "Not an allowed prop for interface");
jchen10880683b2017-04-12 16:21:55 +08001576 return false;
1577 }
1578 }
1579 return true;
1580}
1581
jchen10d9cd7b72017-08-30 15:04:25 +08001582bool ValidateGetProgramInterfaceiv(Context *context,
1583 GLuint program,
1584 GLenum programInterface,
1585 GLenum pname,
1586 GLint *params)
1587{
1588 if (context->getClientVersion() < ES_3_1)
1589 {
Jamie Madille0472f32018-11-27 16:32:45 -05001590 context->validationError(GL_INVALID_OPERATION, kES31Required);
jchen10d9cd7b72017-08-30 15:04:25 +08001591 return false;
1592 }
1593
1594 Program *programObject = GetValidProgram(context, program);
1595 if (programObject == nullptr)
1596 {
1597 return false;
1598 }
1599
1600 if (!ValidateProgramInterface(programInterface))
1601 {
Jamie Madill610640f2018-11-21 17:28:41 -05001602 context->validationError(GL_INVALID_ENUM, "Invalid program interface.");
jchen10d9cd7b72017-08-30 15:04:25 +08001603 return false;
1604 }
1605
1606 switch (pname)
1607 {
1608 case GL_ACTIVE_RESOURCES:
1609 case GL_MAX_NAME_LENGTH:
1610 case GL_MAX_NUM_ACTIVE_VARIABLES:
1611 break;
1612
1613 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001614 context->validationError(GL_INVALID_ENUM, "Unknown property of program interface.");
jchen10d9cd7b72017-08-30 15:04:25 +08001615 return false;
1616 }
1617
1618 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1619 {
Jamie Madill610640f2018-11-21 17:28:41 -05001620 context->validationError(GL_INVALID_OPERATION,
1621 "Active atomic counter resources are not assigned name strings.");
jchen10d9cd7b72017-08-30 15:04:25 +08001622 return false;
1623 }
1624
1625 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1626 {
1627 switch (programInterface)
1628 {
1629 case GL_ATOMIC_COUNTER_BUFFER:
1630 case GL_SHADER_STORAGE_BLOCK:
1631 case GL_UNIFORM_BLOCK:
1632 break;
1633
1634 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001635 context->validationError(
1636 GL_INVALID_OPERATION,
1637 "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
jchen10d9cd7b72017-08-30 15:04:25 +08001638 return false;
1639 }
1640 }
1641
1642 return true;
1643}
1644
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001645bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1646 GLuint program,
1647 GLenum programInterface,
1648 GLenum pname,
1649 GLsizei bufSize,
1650 GLsizei *length,
1651 GLint *params)
1652{
1653 UNIMPLEMENTED();
1654 return false;
1655}
1656
Yunchao Hea336b902017-08-02 16:05:21 +08001657static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1658{
1659 if (context->getClientVersion() < ES_3_1)
1660 {
Jamie Madille0472f32018-11-27 16:32:45 -05001661 context->validationError(GL_INVALID_OPERATION, kES31Required);
Yunchao Hea336b902017-08-02 16:05:21 +08001662 return false;
1663 }
1664
1665 return ValidateGenOrDelete(context, n);
1666}
1667
1668bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1669{
1670 return ValidateGenOrDeleteES31(context, n);
1671}
1672
1673bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1674{
1675 return ValidateGenOrDeleteES31(context, n);
1676}
1677
1678bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1679{
1680 if (context->getClientVersion() < ES_3_1)
1681 {
Jamie Madille0472f32018-11-27 16:32:45 -05001682 context->validationError(GL_INVALID_OPERATION, kES31Required);
Yunchao Hea336b902017-08-02 16:05:21 +08001683 return false;
1684 }
1685
1686 if (!context->isProgramPipelineGenerated(pipeline))
1687 {
Jamie Madille0472f32018-11-27 16:32:45 -05001688 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Yunchao Hea336b902017-08-02 16:05:21 +08001689 return false;
1690 }
1691
1692 return true;
1693}
1694
1695bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1696{
1697 if (context->getClientVersion() < ES_3_1)
1698 {
Jamie Madille0472f32018-11-27 16:32:45 -05001699 context->validationError(GL_INVALID_OPERATION, kES31Required);
Yunchao Hea336b902017-08-02 16:05:21 +08001700 return false;
1701 }
1702
1703 return true;
1704}
1705
Jiajia Qin5451d532017-11-16 17:16:34 +08001706bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1707{
1708 UNIMPLEMENTED();
1709 return false;
1710}
1711
1712bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1713{
1714 UNIMPLEMENTED();
1715 return false;
1716}
1717
1718bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001719 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001720 GLsizei count,
1721 const GLchar *const *strings)
1722{
1723 UNIMPLEMENTED();
1724 return false;
1725}
1726
1727bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1728{
1729 UNIMPLEMENTED();
1730 return false;
1731}
1732
1733bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1734{
1735 UNIMPLEMENTED();
1736 return false;
1737}
1738
1739bool ValidateGetProgramPipelineInfoLog(Context *context,
1740 GLuint pipeline,
1741 GLsizei bufSize,
1742 GLsizei *length,
1743 GLchar *infoLog)
1744{
1745 UNIMPLEMENTED();
1746 return false;
1747}
1748
1749bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1750{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001751 if (context->getClientVersion() < ES_3_1)
1752 {
Jamie Madille0472f32018-11-27 16:32:45 -05001753 context->validationError(GL_INVALID_OPERATION, kES31Required);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001754 return false;
1755 }
1756
1757 if (barriers == GL_ALL_BARRIER_BITS)
1758 {
1759 return true;
1760 }
1761
1762 GLbitfield supported_barrier_bits =
1763 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1764 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1765 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1766 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1767 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1768 if ((barriers & ~supported_barrier_bits) != 0)
1769 {
Jamie Madille0472f32018-11-27 16:32:45 -05001770 context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001771 return false;
1772 }
1773
1774 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001775}
1776
1777bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1778{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001779 if (context->getClientVersion() < ES_3_1)
1780 {
Jamie Madille0472f32018-11-27 16:32:45 -05001781 context->validationError(GL_INVALID_OPERATION, kES31Required);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001782 return false;
1783 }
1784
1785 if (barriers == GL_ALL_BARRIER_BITS)
1786 {
1787 return true;
1788 }
1789
1790 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1791 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1792 GL_SHADER_STORAGE_BARRIER_BIT |
1793 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1794 if ((barriers & ~supported_barrier_bits) != 0)
1795 {
Jamie Madille0472f32018-11-27 16:32:45 -05001796 context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001797 return false;
1798 }
1799
1800 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001801}
1802
1803bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001804{
1805 if (context->getClientVersion() < ES_3_1)
1806 {
Jamie Madille0472f32018-11-27 16:32:45 -05001807 context->validationError(GL_INVALID_OPERATION, kES31Required);
Jiawei Shaodb342272017-09-27 10:21:45 +08001808 return false;
1809 }
1810
Yizhou Jiang7310da32018-11-05 14:40:01 +08001811 return ValidateSampleMaskiBase(context, maskNumber, mask);
Jiawei Shaodb342272017-09-27 10:21:45 +08001812}
1813
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001814bool ValidateFramebufferTextureEXT(Context *context,
1815 GLenum target,
1816 GLenum attachment,
1817 GLuint texture,
1818 GLint level)
1819{
1820 if (!context->getExtensions().geometryShader)
1821 {
Jamie Madille0472f32018-11-27 16:32:45 -05001822 context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001823 return false;
1824 }
1825
1826 if (texture != 0)
1827 {
1828 gl::Texture *tex = context->getTexture(texture);
1829
1830 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
1831 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
1832 // We put this validation before ValidateFramebufferTextureBase because it is an
1833 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
1834 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
1835 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
1836 // existing texture object of type matching textarget.
1837 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
1838 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
1839 // three-dimensional or two-dimensional array texture.
1840 if (tex == nullptr)
1841 {
Jamie Madille0472f32018-11-27 16:32:45 -05001842 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001843 return false;
1844 }
1845
1846 if (!ValidMipLevel(context, tex->getType(), level))
1847 {
Jamie Madille0472f32018-11-27 16:32:45 -05001848 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001849 return false;
1850 }
1851 }
1852
1853 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1854 {
1855 return false;
1856 }
1857
1858 return true;
1859}
1860
Olli Etuaho064458a2018-08-30 14:02:02 +03001861// GL_OES_texture_storage_multisample_2d_array
1862bool ValidateTexStorage3DMultisampleOES(Context *context,
1863 TextureType target,
1864 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05001865 GLenum sizedinternalformat,
Olli Etuaho064458a2018-08-30 14:02:02 +03001866 GLsizei width,
1867 GLsizei height,
1868 GLsizei depth,
1869 GLboolean fixedsamplelocations)
Olli Etuaho89664842018-08-24 14:45:36 +03001870{
Olli Etuaho064458a2018-08-30 14:02:02 +03001871 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03001872 {
Jamie Madille0472f32018-11-27 16:32:45 -05001873 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03001874 return false;
1875 }
1876
1877 if (target != TextureType::_2DMultisampleArray)
1878 {
Jamie Madille0472f32018-11-27 16:32:45 -05001879 context->validationError(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
Olli Etuahod310a432018-08-24 15:40:23 +03001880 return false;
1881 }
1882
1883 if (width < 1 || height < 1 || depth < 1)
1884 {
Jamie Madille0472f32018-11-27 16:32:45 -05001885 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Olli Etuahod310a432018-08-24 15:40:23 +03001886 return false;
1887 }
1888
1889 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
1890 height);
Olli Etuaho89664842018-08-24 14:45:36 +03001891}
1892
Olli Etuaho0ca09752018-09-24 11:00:50 +03001893bool ValidateGetProgramResourceLocationIndexEXT(Context *context,
1894 GLuint program,
1895 GLenum programInterface,
1896 const char *name)
1897{
1898 if (!context->getExtensions().blendFuncExtended)
1899 {
Jamie Madille0472f32018-11-27 16:32:45 -05001900 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001901 return false;
1902 }
1903 if (context->getClientVersion() < ES_3_1)
1904 {
Jamie Madille0472f32018-11-27 16:32:45 -05001905 context->validationError(GL_INVALID_OPERATION, kES31Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001906 return false;
1907 }
1908 if (programInterface != GL_PROGRAM_OUTPUT)
1909 {
Jamie Madille0472f32018-11-27 16:32:45 -05001910 context->validationError(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001911 return false;
1912 }
1913 Program *programObject = GetValidProgram(context, program);
1914 if (!programObject)
1915 {
1916 return false;
1917 }
1918 if (!programObject->isLinked())
1919 {
Jamie Madille0472f32018-11-27 16:32:45 -05001920 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001921 return false;
1922 }
1923 return true;
1924}
1925
Martin Radev66fb8202016-07-28 11:45:20 +03001926} // namespace gl