blob: 258f1530a87715b79b0ea1af1cc0d31fdc92197e [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{
25
jchen1015015f72017-03-16 13:54:21 +080026namespace
27{
28
29bool ValidateNamedProgramInterface(GLenum programInterface)
30{
31 switch (programInterface)
32 {
33 case GL_UNIFORM:
34 case GL_UNIFORM_BLOCK:
35 case GL_PROGRAM_INPUT:
36 case GL_PROGRAM_OUTPUT:
37 case GL_TRANSFORM_FEEDBACK_VARYING:
38 case GL_BUFFER_VARIABLE:
39 case GL_SHADER_STORAGE_BLOCK:
40 return true;
41 default:
42 return false;
43 }
44}
45
jchen10191381f2017-04-11 13:59:04 +080046bool ValidateLocationProgramInterface(GLenum programInterface)
47{
48 switch (programInterface)
49 {
50 case GL_UNIFORM:
51 case GL_PROGRAM_INPUT:
52 case GL_PROGRAM_OUTPUT:
53 return true;
54 default:
55 return false;
56 }
57}
58
jchen10880683b2017-04-12 16:21:55 +080059bool ValidateProgramInterface(GLenum programInterface)
60{
61 return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
62 ValidateNamedProgramInterface(programInterface));
63}
64
Jiawei Shaoc6f82872018-04-24 14:14:50 +080065bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
jchen10880683b2017-04-12 16:21:55 +080066{
Jiawei Shaoc6f82872018-04-24 14:14:50 +080067 ASSERT(context);
jchen10880683b2017-04-12 16:21:55 +080068 switch (prop)
69 {
70 case GL_ACTIVE_VARIABLES:
71 case GL_BUFFER_BINDING:
72 case GL_NUM_ACTIVE_VARIABLES:
73
74 case GL_ARRAY_SIZE:
75
76 case GL_ARRAY_STRIDE:
77 case GL_BLOCK_INDEX:
78 case GL_IS_ROW_MAJOR:
79 case GL_MATRIX_STRIDE:
80
81 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
82
83 case GL_BUFFER_DATA_SIZE:
84
85 case GL_LOCATION:
86
87 case GL_NAME_LENGTH:
88
89 case GL_OFFSET:
90
91 case GL_REFERENCED_BY_VERTEX_SHADER:
92 case GL_REFERENCED_BY_FRAGMENT_SHADER:
93 case GL_REFERENCED_BY_COMPUTE_SHADER:
94
95 case GL_TOP_LEVEL_ARRAY_SIZE:
96 case GL_TOP_LEVEL_ARRAY_STRIDE:
97
98 case GL_TYPE:
99 return true;
100
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800101 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
102 return context->getExtensions().geometryShader;
103
Olli Etuaho0ca09752018-09-24 11:00:50 +0300104 case GL_LOCATION_INDEX_EXT:
105 return context->getExtensions().blendFuncExtended;
106
jchen10880683b2017-04-12 16:21:55 +0800107 default:
108 return false;
109 }
110}
111
112// GLES 3.10 spec: Page 82 -- Table 7.2
113bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
114{
115 switch (prop)
116 {
117 case GL_ACTIVE_VARIABLES:
118 case GL_BUFFER_BINDING:
119 case GL_NUM_ACTIVE_VARIABLES:
120 {
121 switch (programInterface)
122 {
123 case GL_ATOMIC_COUNTER_BUFFER:
124 case GL_SHADER_STORAGE_BLOCK:
125 case GL_UNIFORM_BLOCK:
126 return true;
127 default:
128 return false;
129 }
130 }
131
132 case GL_ARRAY_SIZE:
133 {
134 switch (programInterface)
135 {
136 case GL_BUFFER_VARIABLE:
137 case GL_PROGRAM_INPUT:
138 case GL_PROGRAM_OUTPUT:
139 case GL_TRANSFORM_FEEDBACK_VARYING:
140 case GL_UNIFORM:
141 return true;
142 default:
143 return false;
144 }
145 }
146
147 case GL_ARRAY_STRIDE:
148 case GL_BLOCK_INDEX:
149 case GL_IS_ROW_MAJOR:
150 case GL_MATRIX_STRIDE:
151 {
152 switch (programInterface)
153 {
154 case GL_BUFFER_VARIABLE:
155 case GL_UNIFORM:
156 return true;
157 default:
158 return false;
159 }
160 }
161
162 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
163 {
164 if (programInterface == GL_UNIFORM)
165 {
166 return true;
167 }
168 return false;
169 }
170
171 case GL_BUFFER_DATA_SIZE:
172 {
173 switch (programInterface)
174 {
175 case GL_ATOMIC_COUNTER_BUFFER:
176 case GL_SHADER_STORAGE_BLOCK:
177 case GL_UNIFORM_BLOCK:
178 return true;
179 default:
180 return false;
181 }
182 }
183
184 case GL_LOCATION:
185 {
186 return ValidateLocationProgramInterface(programInterface);
187 }
188
Olli Etuaho0ca09752018-09-24 11:00:50 +0300189 case GL_LOCATION_INDEX_EXT:
190 {
191 // EXT_blend_func_extended
192 return (programInterface == GL_PROGRAM_OUTPUT);
193 }
194
jchen10880683b2017-04-12 16:21:55 +0800195 case GL_NAME_LENGTH:
196 {
197 return ValidateNamedProgramInterface(programInterface);
198 }
199
200 case GL_OFFSET:
201 {
202 switch (programInterface)
203 {
204 case GL_BUFFER_VARIABLE:
205 case GL_UNIFORM:
206 return true;
207 default:
208 return false;
209 }
210 }
211
212 case GL_REFERENCED_BY_VERTEX_SHADER:
213 case GL_REFERENCED_BY_FRAGMENT_SHADER:
214 case GL_REFERENCED_BY_COMPUTE_SHADER:
Jiawei Shaoc6f82872018-04-24 14:14:50 +0800215 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
jchen10880683b2017-04-12 16:21:55 +0800216 {
217 switch (programInterface)
218 {
219 case GL_ATOMIC_COUNTER_BUFFER:
220 case GL_BUFFER_VARIABLE:
221 case GL_PROGRAM_INPUT:
222 case GL_PROGRAM_OUTPUT:
223 case GL_SHADER_STORAGE_BLOCK:
224 case GL_UNIFORM:
225 case GL_UNIFORM_BLOCK:
226 return true;
227 default:
228 return false;
229 }
230 }
231
232 case GL_TOP_LEVEL_ARRAY_SIZE:
233 case GL_TOP_LEVEL_ARRAY_STRIDE:
234 {
235 if (programInterface == GL_BUFFER_VARIABLE)
236 {
237 return true;
238 }
239 return false;
240 }
241
242 case GL_TYPE:
243 {
244 switch (programInterface)
245 {
246 case GL_BUFFER_VARIABLE:
247 case GL_PROGRAM_INPUT:
248 case GL_PROGRAM_OUTPUT:
249 case GL_TRANSFORM_FEEDBACK_VARYING:
250 case GL_UNIFORM:
251 return true;
252 default:
253 return false;
254 }
255 }
256
257 default:
258 return false;
259 }
260}
261
jchen10fd7c3b52017-03-21 15:36:03 +0800262bool ValidateProgramResourceIndex(const Program *programObject,
263 GLenum programInterface,
264 GLuint index)
265{
266 switch (programInterface)
267 {
268 case GL_PROGRAM_INPUT:
269 return (index < static_cast<GLuint>(programObject->getActiveAttributeCount()));
270
271 case GL_PROGRAM_OUTPUT:
272 return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
273
jchen10fd7c3b52017-03-21 15:36:03 +0800274 case GL_UNIFORM:
jchen10baf5d942017-08-28 20:45:48 +0800275 return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
276
Jiajia Qin3a9090f2017-09-27 14:37:04 +0800277 case GL_BUFFER_VARIABLE:
278 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
279
280 case GL_SHADER_STORAGE_BLOCK:
281 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
282
jchen10fd7c3b52017-03-21 15:36:03 +0800283 case GL_UNIFORM_BLOCK:
jchen1058f67be2017-10-27 08:59:27 +0800284 return (index < programObject->getActiveUniformBlockCount());
285
286 case GL_ATOMIC_COUNTER_BUFFER:
287 return (index < programObject->getActiveAtomicCounterBufferCount());
288
jchen10fd7c3b52017-03-21 15:36:03 +0800289 case GL_TRANSFORM_FEEDBACK_VARYING:
jchen10910a3da2017-11-15 09:40:11 +0800290 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
jchen10fd7c3b52017-03-21 15:36:03 +0800291
292 default:
293 UNREACHABLE();
294 return false;
295 }
296}
297
Jamie Madill5b772312018-03-08 20:28:32 -0500298bool ValidateProgramUniform(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800299 GLenum valueType,
300 GLuint program,
301 GLint location,
302 GLsizei count)
303{
304 // Check for ES31 program uniform entry points
305 if (context->getClientVersion() < Version(3, 1))
306 {
Jamie Madill610640f2018-11-21 17:28:41 -0500307 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800308 return false;
309 }
310
311 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500312 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800313 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
314 ValidateUniformValue(context, valueType, uniform->type);
315}
316
Jamie Madill5b772312018-03-08 20:28:32 -0500317bool ValidateProgramUniformMatrix(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800318 GLenum valueType,
319 GLuint program,
320 GLint location,
321 GLsizei count,
322 GLboolean transpose)
323{
324 // Check for ES31 program uniform entry points
325 if (context->getClientVersion() < Version(3, 1))
326 {
Jamie Madill610640f2018-11-21 17:28:41 -0500327 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800328 return false;
329 }
330
331 const LinkedUniform *uniform = nullptr;
Jamie Madill5b772312018-03-08 20:28:32 -0500332 Program *programObject = GetValidProgram(context, program);
Jiajia Qin5451d532017-11-16 17:16:34 +0800333 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
334 ValidateUniformMatrixValue(context, valueType, uniform->type);
335}
336
Jamie Madill5b772312018-03-08 20:28:32 -0500337bool ValidateVertexAttribFormatCommon(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +0800338 GLuint attribIndex,
339 GLint size,
340 GLenum type,
341 GLuint relativeOffset,
342 GLboolean pureInteger)
343{
344 if (context->getClientVersion() < ES_3_1)
345 {
Jamie Madill610640f2018-11-21 17:28:41 -0500346 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Jiajia Qin5451d532017-11-16 17:16:34 +0800347 return false;
348 }
349
350 const Caps &caps = context->getCaps();
351 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
352 {
Jamie Madill610640f2018-11-21 17:28:41 -0500353 context->validationError(GL_INVALID_VALUE, kErrorRelativeOffsetTooLarge);
Jiajia Qin5451d532017-11-16 17:16:34 +0800354 return false;
355 }
356
357 // [OpenGL ES 3.1] Section 10.3.1 page 243:
358 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
359 if (context->getGLState().getVertexArrayId() == 0)
360 {
Jamie Madill610640f2018-11-21 17:28:41 -0500361 context->validationError(GL_INVALID_OPERATION, kErrorDefaultVertexArray);
Jiajia Qin5451d532017-11-16 17:16:34 +0800362 return false;
363 }
364
365 return ValidateVertexFormatBase(context, attribIndex, size, type, pureInteger);
366}
367
jchen1015015f72017-03-16 13:54:21 +0800368} // anonymous namespace
369
Martin Radev66fb8202016-07-28 11:45:20 +0300370bool ValidateGetBooleani_v(Context *context, GLenum target, GLuint index, GLboolean *data)
371{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400372 if (context->getClientVersion() < ES_3_1)
Martin Radev66fb8202016-07-28 11:45:20 +0300373 {
Jamie Madill610640f2018-11-21 17:28:41 -0500374 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Martin Radev66fb8202016-07-28 11:45:20 +0300375 return false;
376 }
377
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400378 if (!ValidateIndexedStateQuery(context, target, index, nullptr))
379 {
380 return false;
381 }
382
383 return true;
384}
385
386bool ValidateGetBooleani_vRobustANGLE(Context *context,
387 GLenum target,
388 GLuint index,
389 GLsizei bufSize,
390 GLsizei *length,
391 GLboolean *data)
392{
Geoff Langeb66a6e2016-10-31 13:06:12 -0400393 if (context->getClientVersion() < ES_3_1)
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400394 {
Jamie Madill610640f2018-11-21 17:28:41 -0500395 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400396 return false;
397 }
398
399 if (!ValidateRobustEntryPoint(context, bufSize))
400 {
401 return false;
402 }
403
Brandon Jonesd1049182018-03-28 10:02:20 -0700404 GLsizei numParams = 0;
405
406 if (!ValidateIndexedStateQuery(context, target, index, &numParams))
Geoff Lang2e43dbb2016-10-14 12:27:35 -0400407 {
408 return false;
409 }
410
Brandon Jonesd1049182018-03-28 10:02:20 -0700411 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Martin Radev66fb8202016-07-28 11:45:20 +0300412 {
413 return false;
414 }
415
Brandon Jonesd1049182018-03-28 10:02:20 -0700416 SetRobustLengthParam(length, numParams);
Martin Radev66fb8202016-07-28 11:45:20 +0300417 return true;
418}
419
Jamie Madill493f9572018-05-24 19:52:15 -0400420bool ValidateDrawIndirectBase(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800421{
422 if (context->getClientVersion() < ES_3_1)
423 {
Jamie Madill610640f2018-11-21 17:28:41 -0500424 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Jiajia Qind9671222016-11-29 16:30:31 +0800425 return false;
426 }
427
428 // Here the third parameter 1 is only to pass the count validation.
429 if (!ValidateDrawBase(context, mode, 1))
430 {
431 return false;
432 }
433
434 const State &state = context->getGLState();
435
436 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
437 // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
438 if (!state.getVertexArrayId())
439 {
Jamie Madill610640f2018-11-21 17:28:41 -0500440 context->validationError(GL_INVALID_OPERATION, kErrorDefaultVertexArray);
Jiajia Qind9671222016-11-29 16:30:31 +0800441 return false;
442 }
443
Jamie Madill5b772312018-03-08 20:28:32 -0500444 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
Jiajia Qind9671222016-11-29 16:30:31 +0800445 if (!drawIndirectBuffer)
446 {
Jamie Madill610640f2018-11-21 17:28:41 -0500447 context->validationError(GL_INVALID_OPERATION, kErrorDrawIndirectBufferNotBound);
Jiajia Qind9671222016-11-29 16:30:31 +0800448 return false;
449 }
450
451 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
452 // machine units, of uint.
453 GLint64 offset = reinterpret_cast<GLint64>(indirect);
454 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
455 {
Jamie Madill610640f2018-11-21 17:28:41 -0500456 context->validationError(GL_INVALID_VALUE, kErrorInvalidIndirectOffset);
Jiajia Qind9671222016-11-29 16:30:31 +0800457 return false;
458 }
459
Martin Radev14a26ae2017-07-24 15:56:29 +0300460 // ANGLE_multiview spec, revision 1:
461 // An INVALID_OPERATION is generated by DrawArraysIndirect and DrawElementsIndirect if the
462 // number of views in the draw framebuffer is greater than 1.
463 const Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
464 ASSERT(drawFramebuffer != nullptr);
465 if (drawFramebuffer->getNumViews() > 1)
466 {
Jamie Madill610640f2018-11-21 17:28:41 -0500467 context->validationError(GL_INVALID_OPERATION, kErrorMultiviewActive);
Martin Radev14a26ae2017-07-24 15:56:29 +0300468 return false;
469 }
470
Jiajia Qind9671222016-11-29 16:30:31 +0800471 return true;
472}
473
Jamie Madill493f9572018-05-24 19:52:15 -0400474bool ValidateDrawArraysIndirect(Context *context, PrimitiveMode mode, const void *indirect)
Jiajia Qind9671222016-11-29 16:30:31 +0800475{
Jamie Madill493f9572018-05-24 19:52:15 -0400476 const State &state = context->getGLState();
477 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
Jiajia Qind9671222016-11-29 16:30:31 +0800478 if (curTransformFeedback && curTransformFeedback->isActive() &&
479 !curTransformFeedback->isPaused())
480 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800481 // EXT_geometry_shader allows transform feedback to work with all draw commands.
482 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
483 if (context->getExtensions().geometryShader)
484 {
485 if (!ValidateTransformFeedbackPrimitiveMode(
486 context, curTransformFeedback->getPrimitiveMode(), mode))
487 {
Jamie Madill610640f2018-11-21 17:28:41 -0500488 context->validationError(GL_INVALID_OPERATION,
489 kErrorInvalidDrawModeTransformFeedback);
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,
498 kErrorUnsupportedDrawModeForTransformFeedback);
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 Madill610640f2018-11-21 17:28:41 -0500514 context->validationError(GL_INVALID_OPERATION, kErrorParamOverflow);
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,
523 GLenum type,
524 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 Madill610640f2018-11-21 17:28:41 -0500536 context->validationError(GL_INVALID_OPERATION, kErrorMustHaveElementArrayBinding);
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 Madill610640f2018-11-21 17:28:41 -0500679 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
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 Madill610640f2018-11-21 17:28:41 -0500895 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
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 Madill610640f2018-11-21 17:28:41 -0500922 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
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 Madill610640f2018-11-21 17:28:41 -0500951 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
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 Madill610640f2018-11-21 17:28:41 -0500963 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800964 return false;
965 }
966
967 if (pname != GL_SAMPLE_POSITION)
968 {
Jamie Madill610640f2018-11-21 17:28:41 -0500969 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800970 return false;
971 }
972
JiangYizhou5b03f472017-01-09 10:22:53 +0800973 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -0400974 GLint samples = framebuffer->getSamples(context);
JiangYizhou5b03f472017-01-09 10:22:53 +0800975
Jamie Madille98b1b52018-03-08 09:47:23 -0500976 if (index >= static_cast<GLuint>(samples))
JiangYizhoubddc46b2016-12-09 09:50:51 +0800977 {
Jamie Madill610640f2018-11-21 17:28:41 -0500978 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsSamples);
JiangYizhoubddc46b2016-12-09 09:50:51 +0800979 return false;
980 }
981
982 return true;
983}
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800984
Brandon Jonesfe4bbe62018-04-06 13:50:14 -0700985bool ValidateGetMultisamplefvRobustANGLE(Context *context,
986 GLenum pname,
987 GLuint index,
988 GLsizei bufSize,
989 GLsizei *length,
990 GLfloat *val)
991{
992 UNIMPLEMENTED();
993 return false;
994}
995
Jiajia Qin5451d532017-11-16 17:16:34 +0800996bool ValidateFramebufferParameteri(Context *context, GLenum target, GLenum pname, GLint param)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +0800997{
998 if (context->getClientVersion() < ES_3_1)
999 {
Jamie Madill610640f2018-11-21 17:28:41 -05001000 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001001 return false;
1002 }
1003
Geoff Lange8afa902017-09-27 15:00:43 -04001004 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001005 {
Jamie Madill610640f2018-11-21 17:28:41 -05001006 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001007 return false;
1008 }
1009
1010 switch (pname)
1011 {
1012 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1013 {
1014 GLint maxWidth = context->getCaps().maxFramebufferWidth;
1015 if (param < 0 || param > maxWidth)
1016 {
Jamie Madill610640f2018-11-21 17:28:41 -05001017 context->validationError(
1018 GL_INVALID_VALUE,
1019 "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001020 return false;
1021 }
1022 break;
1023 }
1024 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1025 {
1026 GLint maxHeight = context->getCaps().maxFramebufferHeight;
1027 if (param < 0 || param > maxHeight)
1028 {
Jamie Madill610640f2018-11-21 17:28:41 -05001029 context->validationError(
1030 GL_INVALID_VALUE,
1031 "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001032 return false;
1033 }
1034 break;
1035 }
1036 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1037 {
1038 GLint maxSamples = context->getCaps().maxFramebufferSamples;
1039 if (param < 0 || param > maxSamples)
1040 {
Jamie Madill610640f2018-11-21 17:28:41 -05001041 context->validationError(
1042 GL_INVALID_VALUE,
1043 "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001044 return false;
1045 }
1046 break;
1047 }
1048 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1049 {
1050 break;
1051 }
Jiawei Shaob1e91382018-05-17 14:33:55 +08001052 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1053 {
1054 if (!context->getExtensions().geometryShader)
1055 {
Jamie Madill610640f2018-11-21 17:28:41 -05001056 context->validationError(GL_INVALID_ENUM, kErrorGeometryShaderExtensionNotEnabled);
Jiawei Shaob1e91382018-05-17 14:33:55 +08001057 return false;
1058 }
1059 GLint maxLayers = context->getCaps().maxFramebufferLayers;
1060 if (param < 0 || param > maxLayers)
1061 {
Jamie Madill610640f2018-11-21 17:28:41 -05001062 context->validationError(GL_INVALID_VALUE, kErrorInvalidFramebufferLayer);
Jiawei Shaob1e91382018-05-17 14:33:55 +08001063 return false;
1064 }
1065 break;
1066 }
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001067 default:
1068 {
Jamie Madill610640f2018-11-21 17:28:41 -05001069 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001070 return false;
1071 }
1072 }
1073
1074 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1075 ASSERT(framebuffer);
1076 if (framebuffer->id() == 0)
1077 {
Jamie Madill610640f2018-11-21 17:28:41 -05001078 context->validationError(GL_INVALID_OPERATION, "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001079 return false;
1080 }
1081 return true;
1082}
1083
Jiajia Qin5451d532017-11-16 17:16:34 +08001084bool ValidateGetFramebufferParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001085{
1086 if (context->getClientVersion() < ES_3_1)
1087 {
Jamie Madill610640f2018-11-21 17:28:41 -05001088 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001089 return false;
1090 }
1091
Geoff Lange8afa902017-09-27 15:00:43 -04001092 if (!ValidFramebufferTarget(context, target))
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001093 {
Jamie Madill610640f2018-11-21 17:28:41 -05001094 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001095 return false;
1096 }
1097
1098 switch (pname)
1099 {
1100 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1101 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1102 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1103 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1104 break;
Jiawei Shaob1e91382018-05-17 14:33:55 +08001105 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1106 if (!context->getExtensions().geometryShader)
1107 {
Jamie Madill610640f2018-11-21 17:28:41 -05001108 context->validationError(GL_INVALID_ENUM, kErrorGeometryShaderExtensionNotEnabled);
Jiawei Shaob1e91382018-05-17 14:33:55 +08001109 return false;
1110 }
1111 break;
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001112 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001113 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001114 return false;
1115 }
1116
1117 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1118 ASSERT(framebuffer);
1119
1120 if (framebuffer->id() == 0)
1121 {
Jamie Madill610640f2018-11-21 17:28:41 -05001122 context->validationError(GL_INVALID_OPERATION, "Default framebuffer is bound to target.");
JiangYizhouf7bbc8a2016-11-16 09:57:22 +08001123 return false;
1124 }
1125 return true;
1126}
1127
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001128bool ValidateGetFramebufferParameterivRobustANGLE(Context *context,
1129 GLenum target,
1130 GLenum pname,
1131 GLsizei bufSize,
1132 GLsizei *length,
1133 GLint *params)
1134{
1135 UNIMPLEMENTED();
1136 return false;
1137}
1138
jchen1015015f72017-03-16 13:54:21 +08001139bool ValidateGetProgramResourceIndex(Context *context,
1140 GLuint program,
1141 GLenum programInterface,
1142 const GLchar *name)
1143{
1144 if (context->getClientVersion() < ES_3_1)
1145 {
Jamie Madill610640f2018-11-21 17:28:41 -05001146 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
jchen1015015f72017-03-16 13:54:21 +08001147 return false;
1148 }
1149
1150 Program *programObject = GetValidProgram(context, program);
1151 if (programObject == nullptr)
1152 {
1153 return false;
1154 }
1155
1156 if (!ValidateNamedProgramInterface(programInterface))
1157 {
Jamie Madill610640f2018-11-21 17:28:41 -05001158 context->validationError(GL_INVALID_ENUM, "Invalid program interface");
jchen1015015f72017-03-16 13:54:21 +08001159 return false;
1160 }
Shao80957d92017-02-20 21:25:59 +08001161
1162 return true;
1163}
1164
Jamie Madill5b772312018-03-08 20:28:32 -05001165bool ValidateBindVertexBuffer(Context *context,
Shao80957d92017-02-20 21:25:59 +08001166 GLuint bindingIndex,
1167 GLuint buffer,
1168 GLintptr offset,
1169 GLsizei stride)
1170{
1171 if (context->getClientVersion() < ES_3_1)
1172 {
Jamie Madill610640f2018-11-21 17:28:41 -05001173 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Shao80957d92017-02-20 21:25:59 +08001174 return false;
1175 }
1176
1177 if (!context->isBufferGenerated(buffer))
1178 {
Jamie Madill610640f2018-11-21 17:28:41 -05001179 context->validationError(GL_INVALID_OPERATION, "Buffer is not generated.");
Shao80957d92017-02-20 21:25:59 +08001180 return false;
1181 }
1182
1183 const Caps &caps = context->getCaps();
1184 if (bindingIndex >= caps.maxVertexAttribBindings)
1185 {
Jamie Madill610640f2018-11-21 17:28:41 -05001186 context->validationError(GL_INVALID_VALUE,
1187 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001188 return false;
1189 }
1190
1191 if (offset < 0)
1192 {
Jamie Madill610640f2018-11-21 17:28:41 -05001193 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Shao80957d92017-02-20 21:25:59 +08001194 return false;
1195 }
1196
1197 if (stride < 0 || stride > caps.maxVertexAttribStride)
1198 {
Jamie Madill610640f2018-11-21 17:28:41 -05001199 context->validationError(GL_INVALID_VALUE,
1200 "stride must be between 0 and MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08001201 return false;
1202 }
1203
1204 // [OpenGL ES 3.1] Section 10.3.1 page 244:
1205 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1206 if (context->getGLState().getVertexArrayId() == 0)
1207 {
Jamie Madill610640f2018-11-21 17:28:41 -05001208 context->validationError(GL_INVALID_OPERATION, "Default vertex array buffer is bound.");
Shao80957d92017-02-20 21:25:59 +08001209 return false;
1210 }
1211
1212 return true;
1213}
1214
Jamie Madill5b772312018-03-08 20:28:32 -05001215bool ValidateVertexBindingDivisor(Context *context, GLuint bindingIndex, GLuint divisor)
Shao80957d92017-02-20 21:25:59 +08001216{
1217 if (context->getClientVersion() < ES_3_1)
1218 {
Jamie Madill610640f2018-11-21 17:28:41 -05001219 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Shao80957d92017-02-20 21:25:59 +08001220 return false;
1221 }
1222
1223 const Caps &caps = context->getCaps();
1224 if (bindingIndex >= caps.maxVertexAttribBindings)
1225 {
Jamie Madill610640f2018-11-21 17:28:41 -05001226 context->validationError(GL_INVALID_VALUE,
1227 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08001228 return false;
1229 }
1230
1231 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1232 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1233 if (context->getGLState().getVertexArrayId() == 0)
1234 {
Jamie Madill610640f2018-11-21 17:28:41 -05001235 context->validationError(GL_INVALID_OPERATION, "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001236 return false;
1237 }
1238
1239 return true;
1240}
1241
Jamie Madill5b772312018-03-08 20:28:32 -05001242bool ValidateVertexAttribFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001243 GLuint attribindex,
Shao80957d92017-02-20 21:25:59 +08001244 GLint size,
1245 GLenum type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001246 GLboolean normalized,
1247 GLuint relativeoffset)
Shao80957d92017-02-20 21:25:59 +08001248{
Jiajia Qin5451d532017-11-16 17:16:34 +08001249 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset,
1250 false);
1251}
Shao80957d92017-02-20 21:25:59 +08001252
Jamie Madill5b772312018-03-08 20:28:32 -05001253bool ValidateVertexAttribIFormat(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08001254 GLuint attribindex,
1255 GLint size,
1256 GLenum type,
1257 GLuint relativeoffset)
1258{
1259 return ValidateVertexAttribFormatCommon(context, attribindex, size, type, relativeoffset, true);
Shao80957d92017-02-20 21:25:59 +08001260}
1261
Jamie Madill5b772312018-03-08 20:28:32 -05001262bool ValidateVertexAttribBinding(Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001263{
1264 if (context->getClientVersion() < ES_3_1)
1265 {
Jamie Madill610640f2018-11-21 17:28:41 -05001266 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Shao80957d92017-02-20 21:25:59 +08001267 return false;
1268 }
1269
1270 // [OpenGL ES 3.1] Section 10.3.1 page 243:
1271 // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1272 if (context->getGLState().getVertexArrayId() == 0)
1273 {
Jamie Madill610640f2018-11-21 17:28:41 -05001274 context->validationError(GL_INVALID_OPERATION, "Default vertex array object is bound.");
Shao80957d92017-02-20 21:25:59 +08001275 return false;
1276 }
1277
1278 const Caps &caps = context->getCaps();
1279 if (attribIndex >= caps.maxVertexAttributes)
1280 {
Jamie Madill610640f2018-11-21 17:28:41 -05001281 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08001282 return false;
1283 }
1284
1285 if (bindingIndex >= caps.maxVertexAttribBindings)
1286 {
Jamie Madill610640f2018-11-21 17:28:41 -05001287 context->validationError(GL_INVALID_VALUE,
1288 "bindingindex must be smaller than MAX_VERTEX_ATTRIB_BINDINGS");
Shao80957d92017-02-20 21:25:59 +08001289 return false;
1290 }
1291
jchen1015015f72017-03-16 13:54:21 +08001292 return true;
1293}
1294
jchen10fd7c3b52017-03-21 15:36:03 +08001295bool ValidateGetProgramResourceName(Context *context,
1296 GLuint program,
1297 GLenum programInterface,
1298 GLuint index,
1299 GLsizei bufSize,
1300 GLsizei *length,
1301 GLchar *name)
1302{
1303 if (context->getClientVersion() < ES_3_1)
1304 {
Jamie Madill610640f2018-11-21 17:28:41 -05001305 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
jchen10fd7c3b52017-03-21 15:36:03 +08001306 return false;
1307 }
1308
1309 Program *programObject = GetValidProgram(context, program);
1310 if (programObject == nullptr)
1311 {
1312 return false;
1313 }
1314
1315 if (!ValidateNamedProgramInterface(programInterface))
1316 {
Jamie Madill610640f2018-11-21 17:28:41 -05001317 context->validationError(GL_INVALID_ENUM, "Invalid program interface");
jchen10fd7c3b52017-03-21 15:36:03 +08001318 return false;
1319 }
1320
1321 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1322 {
Jamie Madill610640f2018-11-21 17:28:41 -05001323 context->validationError(GL_INVALID_VALUE, "Invalid index");
jchen10fd7c3b52017-03-21 15:36:03 +08001324 return false;
1325 }
1326
1327 if (bufSize < 0)
1328 {
Jamie Madill610640f2018-11-21 17:28:41 -05001329 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
jchen10fd7c3b52017-03-21 15:36:03 +08001330 return false;
1331 }
1332
1333 return true;
1334}
1335
Xinghua Cao2b396592017-03-29 15:36:04 +08001336bool ValidateDispatchCompute(Context *context,
1337 GLuint numGroupsX,
1338 GLuint numGroupsY,
1339 GLuint numGroupsZ)
1340{
1341 if (context->getClientVersion() < ES_3_1)
1342 {
Jamie Madill610640f2018-11-21 17:28:41 -05001343 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Xinghua Cao2b396592017-03-29 15:36:04 +08001344 return false;
1345 }
1346
1347 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001348 Program *program = state.getLinkedProgram(context);
Xinghua Cao2b396592017-03-29 15:36:04 +08001349
Jiawei Shao385b3e02018-03-21 09:43:28 +08001350 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Xinghua Cao2b396592017-03-29 15:36:04 +08001351 {
Jamie Madill610640f2018-11-21 17:28:41 -05001352 context->validationError(GL_INVALID_OPERATION, kErrorNoActiveProgramWithComputeShader);
Xinghua Cao2b396592017-03-29 15:36:04 +08001353 return false;
1354 }
1355
1356 const Caps &caps = context->getCaps();
1357 if (numGroupsX > caps.maxComputeWorkGroupCount[0])
1358 {
Jamie Madill610640f2018-11-21 17:28:41 -05001359 context->validationError(
1360 GL_INVALID_VALUE,
1361 "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]");
Xinghua Cao2b396592017-03-29 15:36:04 +08001362 return false;
1363 }
1364 if (numGroupsY > caps.maxComputeWorkGroupCount[1])
1365 {
Jamie Madill610640f2018-11-21 17:28:41 -05001366 context->validationError(
1367 GL_INVALID_VALUE,
1368 "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]");
Xinghua Cao2b396592017-03-29 15:36:04 +08001369 return false;
1370 }
1371 if (numGroupsZ > caps.maxComputeWorkGroupCount[2])
1372 {
Jamie Madill610640f2018-11-21 17:28:41 -05001373 context->validationError(
1374 GL_INVALID_VALUE,
1375 "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]");
Xinghua Cao2b396592017-03-29 15:36:04 +08001376 return false;
1377 }
1378
1379 return true;
1380}
1381
Jiajia Qin5451d532017-11-16 17:16:34 +08001382bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
1383{
Qin Jiajia62fcf622017-11-30 16:16:12 +08001384 if (context->getClientVersion() < ES_3_1)
1385 {
Jamie Madill610640f2018-11-21 17:28:41 -05001386 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001387 return false;
1388 }
1389
1390 const State &state = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -04001391 Program *program = state.getLinkedProgram(context);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001392
Jiawei Shao385b3e02018-03-21 09:43:28 +08001393 if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
Qin Jiajia62fcf622017-11-30 16:16:12 +08001394 {
Jamie Madill610640f2018-11-21 17:28:41 -05001395 context->validationError(GL_INVALID_OPERATION, kErrorNoActiveProgramWithComputeShader);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001396 return false;
1397 }
1398
Qin Jiajia62fcf622017-11-30 16:16:12 +08001399 if (indirect < 0)
1400 {
Jamie Madill610640f2018-11-21 17:28:41 -05001401 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001402 return false;
1403 }
1404
1405 if ((indirect & (sizeof(GLuint) - 1)) != 0)
1406 {
Jamie Madill610640f2018-11-21 17:28:41 -05001407 context->validationError(GL_INVALID_VALUE, kErrorOffsetMustBeMultipleOfUint);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001408 return false;
1409 }
1410
Jamie Madill5b772312018-03-08 20:28:32 -05001411 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
Qin Jiajiaa4ef8432018-02-22 16:02:24 +08001412 if (!dispatchIndirectBuffer)
1413 {
Jamie Madill610640f2018-11-21 17:28:41 -05001414 context->validationError(GL_INVALID_OPERATION, kErrorDispatchIndirectBufferNotBound);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001415 return false;
1416 }
1417
1418 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1419 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1420 if (!checkedSum.IsValid() ||
1421 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1422 {
Jamie Madill610640f2018-11-21 17:28:41 -05001423 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Qin Jiajia62fcf622017-11-30 16:16:12 +08001424 return false;
1425 }
1426
1427 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001428}
1429
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001430bool ValidateBindImageTexture(Context *context,
1431 GLuint unit,
1432 GLuint texture,
1433 GLint level,
1434 GLboolean layered,
1435 GLint layer,
1436 GLenum access,
1437 GLenum format)
1438{
1439 GLuint maxImageUnits = context->getCaps().maxImageUnits;
1440 if (unit >= maxImageUnits)
1441 {
Jamie Madill610640f2018-11-21 17:28:41 -05001442 context->validationError(GL_INVALID_VALUE,
1443 "unit cannot be greater than or equal than MAX_IMAGE_UNITS");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001444 return false;
1445 }
1446
1447 if (level < 0)
1448 {
Jamie Madill610640f2018-11-21 17:28:41 -05001449 context->validationError(GL_INVALID_VALUE, "level is negative.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001450 return false;
1451 }
1452
1453 if (layer < 0)
1454 {
Jamie Madill610640f2018-11-21 17:28:41 -05001455 context->validationError(GL_INVALID_VALUE, "layer is negative.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001456 return false;
1457 }
1458
1459 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1460 {
Jamie Madill610640f2018-11-21 17:28:41 -05001461 context->validationError(GL_INVALID_ENUM, "access is not one of the supported tokens.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001462 return false;
1463 }
1464
1465 switch (format)
1466 {
1467 case GL_RGBA32F:
1468 case GL_RGBA16F:
1469 case GL_R32F:
1470 case GL_RGBA32UI:
1471 case GL_RGBA16UI:
1472 case GL_RGBA8UI:
1473 case GL_R32UI:
1474 case GL_RGBA32I:
1475 case GL_RGBA16I:
1476 case GL_RGBA8I:
1477 case GL_R32I:
1478 case GL_RGBA8:
1479 case GL_RGBA8_SNORM:
1480 break;
1481 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001482 context->validationError(GL_INVALID_VALUE,
1483 "format is not one of supported image unit formats.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001484 return false;
1485 }
1486
1487 if (texture != 0)
1488 {
1489 Texture *tex = context->getTexture(texture);
1490
1491 if (tex == nullptr)
1492 {
Jamie Madill610640f2018-11-21 17:28:41 -05001493 context->validationError(GL_INVALID_VALUE,
1494 "texture is not the name of an existing texture object.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001495 return false;
1496 }
1497
1498 if (!tex->getImmutableFormat())
1499 {
Jamie Madill610640f2018-11-21 17:28:41 -05001500 context->validationError(GL_INVALID_OPERATION,
1501 "texture is not the name of an immutable texture object.");
Xinghua Cao65ec0b22017-03-28 16:10:52 +08001502 return false;
1503 }
1504 }
1505
1506 return true;
1507}
jchen10191381f2017-04-11 13:59:04 +08001508
1509bool ValidateGetProgramResourceLocation(Context *context,
1510 GLuint program,
1511 GLenum programInterface,
1512 const GLchar *name)
1513{
1514 if (context->getClientVersion() < ES_3_1)
1515 {
Jamie Madill610640f2018-11-21 17:28:41 -05001516 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
jchen10191381f2017-04-11 13:59:04 +08001517 return false;
1518 }
1519
1520 Program *programObject = GetValidProgram(context, program);
1521 if (programObject == nullptr)
1522 {
1523 return false;
1524 }
1525
1526 if (!programObject->isLinked())
1527 {
Jamie Madill610640f2018-11-21 17:28:41 -05001528 context->validationError(GL_INVALID_OPERATION, "Program is not successfully linked.");
jchen10191381f2017-04-11 13:59:04 +08001529 return false;
1530 }
1531
1532 if (!ValidateLocationProgramInterface(programInterface))
1533 {
Jamie Madill610640f2018-11-21 17:28:41 -05001534 context->validationError(GL_INVALID_ENUM, "Invalid program interface.");
jchen10191381f2017-04-11 13:59:04 +08001535 return false;
1536 }
1537 return true;
1538}
1539
jchen10880683b2017-04-12 16:21:55 +08001540bool ValidateGetProgramResourceiv(Context *context,
1541 GLuint program,
1542 GLenum programInterface,
1543 GLuint index,
1544 GLsizei propCount,
1545 const GLenum *props,
1546 GLsizei bufSize,
1547 GLsizei *length,
1548 GLint *params)
1549{
1550 if (context->getClientVersion() < ES_3_1)
1551 {
Jamie Madill610640f2018-11-21 17:28:41 -05001552 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
jchen10880683b2017-04-12 16:21:55 +08001553 return false;
1554 }
1555
1556 Program *programObject = GetValidProgram(context, program);
1557 if (programObject == nullptr)
1558 {
1559 return false;
1560 }
1561 if (!ValidateProgramInterface(programInterface))
1562 {
Jamie Madill610640f2018-11-21 17:28:41 -05001563 context->validationError(GL_INVALID_ENUM, "Invalid program interface.");
jchen10880683b2017-04-12 16:21:55 +08001564 return false;
1565 }
1566 if (propCount <= 0)
1567 {
Jamie Madill610640f2018-11-21 17:28:41 -05001568 context->validationError(GL_INVALID_VALUE, "Invalid propCount.");
jchen10880683b2017-04-12 16:21:55 +08001569 return false;
1570 }
1571 if (bufSize < 0)
1572 {
Jamie Madill610640f2018-11-21 17:28:41 -05001573 context->validationError(GL_INVALID_VALUE, "Invalid bufSize.");
jchen10880683b2017-04-12 16:21:55 +08001574 return false;
1575 }
1576 if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1577 {
Jamie Madill610640f2018-11-21 17:28:41 -05001578 context->validationError(GL_INVALID_VALUE, "Invalid index");
jchen10880683b2017-04-12 16:21:55 +08001579 return false;
1580 }
1581 for (GLsizei i = 0; i < propCount; i++)
1582 {
Jiawei Shaoc6f82872018-04-24 14:14:50 +08001583 if (!ValidateProgramResourceProperty(context, props[i]))
jchen10880683b2017-04-12 16:21:55 +08001584 {
Jamie Madill610640f2018-11-21 17:28:41 -05001585 context->validationError(GL_INVALID_ENUM, "Invalid prop.");
jchen10880683b2017-04-12 16:21:55 +08001586 return false;
1587 }
1588 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1589 {
Jamie Madill610640f2018-11-21 17:28:41 -05001590 context->validationError(GL_INVALID_OPERATION, "Not an allowed prop for interface");
jchen10880683b2017-04-12 16:21:55 +08001591 return false;
1592 }
1593 }
1594 return true;
1595}
1596
jchen10d9cd7b72017-08-30 15:04:25 +08001597bool ValidateGetProgramInterfaceiv(Context *context,
1598 GLuint program,
1599 GLenum programInterface,
1600 GLenum pname,
1601 GLint *params)
1602{
1603 if (context->getClientVersion() < ES_3_1)
1604 {
Jamie Madill610640f2018-11-21 17:28:41 -05001605 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
jchen10d9cd7b72017-08-30 15:04:25 +08001606 return false;
1607 }
1608
1609 Program *programObject = GetValidProgram(context, program);
1610 if (programObject == nullptr)
1611 {
1612 return false;
1613 }
1614
1615 if (!ValidateProgramInterface(programInterface))
1616 {
Jamie Madill610640f2018-11-21 17:28:41 -05001617 context->validationError(GL_INVALID_ENUM, "Invalid program interface.");
jchen10d9cd7b72017-08-30 15:04:25 +08001618 return false;
1619 }
1620
1621 switch (pname)
1622 {
1623 case GL_ACTIVE_RESOURCES:
1624 case GL_MAX_NAME_LENGTH:
1625 case GL_MAX_NUM_ACTIVE_VARIABLES:
1626 break;
1627
1628 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001629 context->validationError(GL_INVALID_ENUM, "Unknown property of program interface.");
jchen10d9cd7b72017-08-30 15:04:25 +08001630 return false;
1631 }
1632
1633 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1634 {
Jamie Madill610640f2018-11-21 17:28:41 -05001635 context->validationError(GL_INVALID_OPERATION,
1636 "Active atomic counter resources are not assigned name strings.");
jchen10d9cd7b72017-08-30 15:04:25 +08001637 return false;
1638 }
1639
1640 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1641 {
1642 switch (programInterface)
1643 {
1644 case GL_ATOMIC_COUNTER_BUFFER:
1645 case GL_SHADER_STORAGE_BLOCK:
1646 case GL_UNIFORM_BLOCK:
1647 break;
1648
1649 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001650 context->validationError(
1651 GL_INVALID_OPERATION,
1652 "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.");
jchen10d9cd7b72017-08-30 15:04:25 +08001653 return false;
1654 }
1655 }
1656
1657 return true;
1658}
1659
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07001660bool ValidateGetProgramInterfaceivRobustANGLE(Context *context,
1661 GLuint program,
1662 GLenum programInterface,
1663 GLenum pname,
1664 GLsizei bufSize,
1665 GLsizei *length,
1666 GLint *params)
1667{
1668 UNIMPLEMENTED();
1669 return false;
1670}
1671
Yunchao Hea336b902017-08-02 16:05:21 +08001672static bool ValidateGenOrDeleteES31(Context *context, GLint n)
1673{
1674 if (context->getClientVersion() < ES_3_1)
1675 {
Jamie Madill610640f2018-11-21 17:28:41 -05001676 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Yunchao Hea336b902017-08-02 16:05:21 +08001677 return false;
1678 }
1679
1680 return ValidateGenOrDelete(context, n);
1681}
1682
1683bool ValidateGenProgramPipelines(Context *context, GLint n, GLuint *)
1684{
1685 return ValidateGenOrDeleteES31(context, n);
1686}
1687
1688bool ValidateDeleteProgramPipelines(Context *context, GLint n, const GLuint *)
1689{
1690 return ValidateGenOrDeleteES31(context, n);
1691}
1692
1693bool ValidateBindProgramPipeline(Context *context, GLuint pipeline)
1694{
1695 if (context->getClientVersion() < ES_3_1)
1696 {
Jamie Madill610640f2018-11-21 17:28:41 -05001697 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Yunchao Hea336b902017-08-02 16:05:21 +08001698 return false;
1699 }
1700
1701 if (!context->isProgramPipelineGenerated(pipeline))
1702 {
Jamie Madill610640f2018-11-21 17:28:41 -05001703 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Yunchao Hea336b902017-08-02 16:05:21 +08001704 return false;
1705 }
1706
1707 return true;
1708}
1709
1710bool ValidateIsProgramPipeline(Context *context, GLuint pipeline)
1711{
1712 if (context->getClientVersion() < ES_3_1)
1713 {
Jamie Madill610640f2018-11-21 17:28:41 -05001714 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Yunchao Hea336b902017-08-02 16:05:21 +08001715 return false;
1716 }
1717
1718 return true;
1719}
1720
Jiajia Qin5451d532017-11-16 17:16:34 +08001721bool ValidateUseProgramStages(Context *context, GLuint pipeline, GLbitfield stages, GLuint program)
1722{
1723 UNIMPLEMENTED();
1724 return false;
1725}
1726
1727bool ValidateActiveShaderProgram(Context *context, GLuint pipeline, GLuint program)
1728{
1729 UNIMPLEMENTED();
1730 return false;
1731}
1732
1733bool ValidateCreateShaderProgramv(Context *context,
Jiawei Shao385b3e02018-03-21 09:43:28 +08001734 ShaderType type,
Jiajia Qin5451d532017-11-16 17:16:34 +08001735 GLsizei count,
1736 const GLchar *const *strings)
1737{
1738 UNIMPLEMENTED();
1739 return false;
1740}
1741
1742bool ValidateGetProgramPipelineiv(Context *context, GLuint pipeline, GLenum pname, GLint *params)
1743{
1744 UNIMPLEMENTED();
1745 return false;
1746}
1747
1748bool ValidateValidateProgramPipeline(Context *context, GLuint pipeline)
1749{
1750 UNIMPLEMENTED();
1751 return false;
1752}
1753
1754bool ValidateGetProgramPipelineInfoLog(Context *context,
1755 GLuint pipeline,
1756 GLsizei bufSize,
1757 GLsizei *length,
1758 GLchar *infoLog)
1759{
1760 UNIMPLEMENTED();
1761 return false;
1762}
1763
1764bool ValidateMemoryBarrier(Context *context, GLbitfield barriers)
1765{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001766 if (context->getClientVersion() < ES_3_1)
1767 {
Jamie Madill610640f2018-11-21 17:28:41 -05001768 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001769 return false;
1770 }
1771
1772 if (barriers == GL_ALL_BARRIER_BITS)
1773 {
1774 return true;
1775 }
1776
1777 GLbitfield supported_barrier_bits =
1778 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1779 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1780 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1781 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1782 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1783 if ((barriers & ~supported_barrier_bits) != 0)
1784 {
Jamie Madill610640f2018-11-21 17:28:41 -05001785 context->validationError(GL_INVALID_VALUE, kErrorInvalidMemoryBarrierBit);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001786 return false;
1787 }
1788
1789 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001790}
1791
1792bool ValidateMemoryBarrierByRegion(Context *context, GLbitfield barriers)
1793{
Xinghua Cao89c422a2017-11-29 18:24:20 +08001794 if (context->getClientVersion() < ES_3_1)
1795 {
Jamie Madill610640f2018-11-21 17:28:41 -05001796 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001797 return false;
1798 }
1799
1800 if (barriers == GL_ALL_BARRIER_BITS)
1801 {
1802 return true;
1803 }
1804
1805 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1806 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1807 GL_SHADER_STORAGE_BARRIER_BIT |
1808 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1809 if ((barriers & ~supported_barrier_bits) != 0)
1810 {
Jamie Madill610640f2018-11-21 17:28:41 -05001811 context->validationError(GL_INVALID_VALUE, kErrorInvalidMemoryBarrierBit);
Xinghua Cao89c422a2017-11-29 18:24:20 +08001812 return false;
1813 }
1814
1815 return true;
Jiajia Qin5451d532017-11-16 17:16:34 +08001816}
1817
1818bool ValidateSampleMaski(Context *context, GLuint maskNumber, GLbitfield mask)
Jiawei Shaodb342272017-09-27 10:21:45 +08001819{
1820 if (context->getClientVersion() < ES_3_1)
1821 {
Jamie Madill610640f2018-11-21 17:28:41 -05001822 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Jiawei Shaodb342272017-09-27 10:21:45 +08001823 return false;
1824 }
1825
1826 if (maskNumber >= context->getCaps().maxSampleMaskWords)
1827 {
Jamie Madill610640f2018-11-21 17:28:41 -05001828 context->validationError(GL_INVALID_VALUE, kErrorInvalidSampleMaskNumber);
Jiawei Shaodb342272017-09-27 10:21:45 +08001829 return false;
1830 }
1831
1832 return true;
1833}
1834
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001835bool ValidateFramebufferTextureEXT(Context *context,
1836 GLenum target,
1837 GLenum attachment,
1838 GLuint texture,
1839 GLint level)
1840{
1841 if (!context->getExtensions().geometryShader)
1842 {
Jamie Madill610640f2018-11-21 17:28:41 -05001843 context->validationError(GL_INVALID_OPERATION, kErrorGeometryShaderExtensionNotEnabled);
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001844 return false;
1845 }
1846
1847 if (texture != 0)
1848 {
1849 gl::Texture *tex = context->getTexture(texture);
1850
1851 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
1852 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
1853 // We put this validation before ValidateFramebufferTextureBase because it is an
1854 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
1855 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
1856 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
1857 // existing texture object of type matching textarget.
1858 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
1859 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
1860 // three-dimensional or two-dimensional array texture.
1861 if (tex == nullptr)
1862 {
Jamie Madill610640f2018-11-21 17:28:41 -05001863 context->validationError(GL_INVALID_VALUE, kErrorInvalidTextureName);
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001864 return false;
1865 }
1866
1867 if (!ValidMipLevel(context, tex->getType(), level))
1868 {
Jamie Madill610640f2018-11-21 17:28:41 -05001869 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Jiawei Shao5f9482f2018-05-18 09:00:09 +08001870 return false;
1871 }
1872 }
1873
1874 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1875 {
1876 return false;
1877 }
1878
1879 return true;
1880}
1881
Olli Etuaho064458a2018-08-30 14:02:02 +03001882// GL_OES_texture_storage_multisample_2d_array
1883bool ValidateTexStorage3DMultisampleOES(Context *context,
1884 TextureType target,
1885 GLsizei samples,
Jamie Madill778bf092018-11-14 09:54:36 -05001886 GLenum sizedinternalformat,
Olli Etuaho064458a2018-08-30 14:02:02 +03001887 GLsizei width,
1888 GLsizei height,
1889 GLsizei depth,
1890 GLboolean fixedsamplelocations)
Olli Etuaho89664842018-08-24 14:45:36 +03001891{
Olli Etuaho064458a2018-08-30 14:02:02 +03001892 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03001893 {
Jamie Madill610640f2018-11-21 17:28:41 -05001894 context->validationError(GL_INVALID_ENUM, kErrorMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03001895 return false;
1896 }
1897
1898 if (target != TextureType::_2DMultisampleArray)
1899 {
Jamie Madill610640f2018-11-21 17:28:41 -05001900 context->validationError(GL_INVALID_ENUM, kErrorTargetMustBeTexture2DMultisampleArrayOES);
Olli Etuahod310a432018-08-24 15:40:23 +03001901 return false;
1902 }
1903
1904 if (width < 1 || height < 1 || depth < 1)
1905 {
Jamie Madill610640f2018-11-21 17:28:41 -05001906 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Olli Etuahod310a432018-08-24 15:40:23 +03001907 return false;
1908 }
1909
1910 return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
1911 height);
Olli Etuaho89664842018-08-24 14:45:36 +03001912}
1913
Olli Etuaho0ca09752018-09-24 11:00:50 +03001914bool ValidateGetProgramResourceLocationIndexEXT(Context *context,
1915 GLuint program,
1916 GLenum programInterface,
1917 const char *name)
1918{
1919 if (!context->getExtensions().blendFuncExtended)
1920 {
Jamie Madill610640f2018-11-21 17:28:41 -05001921 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001922 return false;
1923 }
1924 if (context->getClientVersion() < ES_3_1)
1925 {
Jamie Madill610640f2018-11-21 17:28:41 -05001926 context->validationError(GL_INVALID_OPERATION, kErrorES31Required);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001927 return false;
1928 }
1929 if (programInterface != GL_PROGRAM_OUTPUT)
1930 {
Jamie Madill610640f2018-11-21 17:28:41 -05001931 context->validationError(GL_INVALID_ENUM, kErrorProgramInterfaceMustBeProgramOutput);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001932 return false;
1933 }
1934 Program *programObject = GetValidProgram(context, program);
1935 if (!programObject)
1936 {
1937 return false;
1938 }
1939 if (!programObject->isLinked())
1940 {
Jamie Madill610640f2018-11-21 17:28:41 -05001941 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Olli Etuaho0ca09752018-09-24 11:00:50 +03001942 return false;
1943 }
1944 return true;
1945}
1946
Martin Radev66fb8202016-07-28 11:45:20 +03001947} // namespace gl