1 //
2 // Copyright 2019 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 // validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
7
8 #include "libANGLE/validationESEXT_autogen.h"
9
10 #include "libANGLE/Context.h"
11 #include "libANGLE/ErrorStrings.h"
12 #include "libANGLE/validationES.h"
13 #include "libANGLE/validationES32.h"
14
15 namespace gl
16 {
17 using namespace err;
18
19 namespace
20 {
21 template <typename ObjectT>
ValidateGetImageFormatAndType(const Context * context,ObjectT * obj,GLenum format,GLenum type)22 bool ValidateGetImageFormatAndType(const Context *context, ObjectT *obj, GLenum format, GLenum type)
23 {
24 GLenum implFormat = obj->getImplementationColorReadFormat(context);
25 if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
26 {
27 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
28 return false;
29 }
30
31 GLenum implType = obj->getImplementationColorReadType(context);
32 if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
33 {
34 context->validationError(GL_INVALID_ENUM, kInvalidType);
35 return false;
36 }
37
38 // Format/type combinations are not yet validated.
39
40 return true;
41 }
42
43 } // namespace
44
ValidateGetTexImageANGLE(const Context * context,TextureTarget target,GLint level,GLenum format,GLenum type,const void * pixels)45 bool ValidateGetTexImageANGLE(const Context *context,
46 TextureTarget target,
47 GLint level,
48 GLenum format,
49 GLenum type,
50 const void *pixels)
51 {
52 if (!context->getExtensions().getImageANGLE)
53 {
54 context->validationError(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
55 return false;
56 }
57
58 if (!ValidTexture2DDestinationTarget(context, target) &&
59 !ValidTexture3DDestinationTarget(context, target))
60 {
61 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
62 return false;
63 }
64
65 if (level < 0)
66 {
67 context->validationError(GL_INVALID_VALUE, kNegativeLevel);
68 return false;
69 }
70
71 TextureType textureType = TextureTargetToType(target);
72 if (!ValidMipLevel(context, textureType, level))
73 {
74 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
75 return false;
76 }
77
78 Texture *texture = context->getTextureByTarget(target);
79
80 if (!ValidateGetImageFormatAndType(context, texture, format, type))
81 {
82 return false;
83 }
84
85 GLsizei width = static_cast<GLsizei>(texture->getWidth(target, level));
86 GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
87 if (!ValidatePixelPack(context, format, type, 0, 0, width, height, -1, nullptr, pixels))
88 {
89 return false;
90 }
91
92 return true;
93 }
94
ValidateGetRenderbufferImageANGLE(const Context * context,GLenum target,GLenum format,GLenum type,const void * pixels)95 bool ValidateGetRenderbufferImageANGLE(const Context *context,
96 GLenum target,
97 GLenum format,
98 GLenum type,
99 const void *pixels)
100 {
101 if (!context->getExtensions().getImageANGLE)
102 {
103 context->validationError(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
104 return false;
105 }
106
107 if (target != GL_RENDERBUFFER)
108 {
109 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
110 return false;
111 }
112
113 Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
114
115 if (!ValidateGetImageFormatAndType(context, renderbuffer, format, type))
116 {
117 return false;
118 }
119
120 GLsizei width = renderbuffer->getWidth();
121 GLsizei height = renderbuffer->getHeight();
122 if (!ValidatePixelPack(context, format, type, 0, 0, width, height, -1, nullptr, pixels))
123 {
124 return false;
125 }
126
127 return true;
128 }
129
ValidateDrawElementsBaseVertexEXT(const Context * context,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)130 bool ValidateDrawElementsBaseVertexEXT(const Context *context,
131 PrimitiveMode mode,
132 GLsizei count,
133 DrawElementsType type,
134 const void *indices,
135 GLint basevertex)
136 {
137 if (!context->getExtensions().drawElementsBaseVertexAny())
138 {
139 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
140 return false;
141 }
142
143 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
144 }
145
ValidateDrawElementsInstancedBaseVertexEXT(const Context * context,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)146 bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
147 PrimitiveMode mode,
148 GLsizei count,
149 DrawElementsType type,
150 const void *indices,
151 GLsizei instancecount,
152 GLint basevertex)
153 {
154 if (!context->getExtensions().drawElementsBaseVertexAny())
155 {
156 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
157 return false;
158 }
159
160 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, instancecount);
161 }
162
ValidateDrawRangeElementsBaseVertexEXT(const Context * context,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)163 bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
164 PrimitiveMode mode,
165 GLuint start,
166 GLuint end,
167 GLsizei count,
168 DrawElementsType type,
169 const void *indices,
170 GLint basevertex)
171 {
172 if (!context->getExtensions().drawElementsBaseVertexAny())
173 {
174 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
175 return false;
176 }
177
178 if (end < start)
179 {
180 context->validationError(GL_INVALID_VALUE, kInvalidElementRange);
181 return false;
182 }
183
184 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
185 {
186 return false;
187 }
188
189 // Skip range checks for no-op calls.
190 if (count <= 0)
191 {
192 return true;
193 }
194
195 // Note that resolving the index range is a bit slow. We should probably optimize this.
196 IndexRange indexRange;
197 ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
198 indices, &indexRange));
199
200 if (indexRange.end > end || indexRange.start < start)
201 {
202 // GL spec says that behavior in this case is undefined - generating an error is fine.
203 context->validationError(GL_INVALID_OPERATION, kExceedsElementRange);
204 return false;
205 }
206 return true;
207 }
208
ValidateMultiDrawElementsBaseVertexEXT(const Context * context,PrimitiveMode mode,const GLsizei * count,DrawElementsType type,const void * const * indices,GLsizei drawcount,const GLint * basevertex)209 bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
210 PrimitiveMode mode,
211 const GLsizei *count,
212 DrawElementsType type,
213 const void *const *indices,
214 GLsizei drawcount,
215 const GLint *basevertex)
216 {
217 return true;
218 }
219
ValidateDrawElementsBaseVertexOES(const Context * context,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)220 bool ValidateDrawElementsBaseVertexOES(const Context *context,
221 PrimitiveMode mode,
222 GLsizei count,
223 DrawElementsType type,
224 const void *indices,
225 GLint basevertex)
226 {
227 if (!context->getExtensions().drawElementsBaseVertexAny())
228 {
229 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
230 return false;
231 }
232
233 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
234 }
235
ValidateDrawElementsInstancedBaseVertexOES(const Context * context,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)236 bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
237 PrimitiveMode mode,
238 GLsizei count,
239 DrawElementsType type,
240 const void *indices,
241 GLsizei instancecount,
242 GLint basevertex)
243 {
244 if (!context->getExtensions().drawElementsBaseVertexAny())
245 {
246 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
247 return false;
248 }
249
250 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, instancecount);
251 }
252
ValidateDrawRangeElementsBaseVertexOES(const Context * context,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)253 bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
254 PrimitiveMode mode,
255 GLuint start,
256 GLuint end,
257 GLsizei count,
258 DrawElementsType type,
259 const void *indices,
260 GLint basevertex)
261 {
262 if (!context->getExtensions().drawElementsBaseVertexAny())
263 {
264 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
265 return false;
266 }
267
268 if (end < start)
269 {
270 context->validationError(GL_INVALID_VALUE, kInvalidElementRange);
271 return false;
272 }
273
274 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
275 {
276 return false;
277 }
278
279 // Skip range checks for no-op calls.
280 if (count <= 0)
281 {
282 return true;
283 }
284
285 // Note that resolving the index range is a bit slow. We should probably optimize this.
286 IndexRange indexRange;
287 ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
288 indices, &indexRange));
289
290 if (indexRange.end > end || indexRange.start < start)
291 {
292 // GL spec says that behavior in this case is undefined - generating an error is fine.
293 context->validationError(GL_INVALID_OPERATION, kExceedsElementRange);
294 return false;
295 }
296 return true;
297 }
298
ValidateBlendEquationSeparateiEXT(const Context * context,GLuint buf,GLenum modeRGB,GLenum modeAlpha)299 bool ValidateBlendEquationSeparateiEXT(const Context *context,
300 GLuint buf,
301 GLenum modeRGB,
302 GLenum modeAlpha)
303 {
304 if (!context->getExtensions().drawBuffersIndexedEXT)
305 {
306 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
307 return false;
308 }
309
310 return ValidateBlendEquationSeparatei(context, buf, modeRGB, modeAlpha);
311 }
312
ValidateBlendEquationiEXT(const Context * context,GLuint buf,GLenum mode)313 bool ValidateBlendEquationiEXT(const Context *context, GLuint buf, GLenum mode)
314 {
315 if (!context->getExtensions().drawBuffersIndexedEXT)
316 {
317 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
318 return false;
319 }
320
321 return ValidateBlendEquationi(context, buf, mode);
322 }
323
ValidateBlendFuncSeparateiEXT(const Context * context,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)324 bool ValidateBlendFuncSeparateiEXT(const Context *context,
325 GLuint buf,
326 GLenum srcRGB,
327 GLenum dstRGB,
328 GLenum srcAlpha,
329 GLenum dstAlpha)
330 {
331 if (!context->getExtensions().drawBuffersIndexedEXT)
332 {
333 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
334 return false;
335 }
336
337 return ValidateBlendFuncSeparatei(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
338 }
339
ValidateBlendFunciEXT(const Context * context,GLuint buf,GLenum src,GLenum dst)340 bool ValidateBlendFunciEXT(const Context *context, GLuint buf, GLenum src, GLenum dst)
341 {
342 if (!context->getExtensions().drawBuffersIndexedEXT)
343 {
344 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
345 return false;
346 }
347
348 return ValidateBlendFunci(context, buf, src, dst);
349 }
350
ValidateColorMaskiEXT(const Context * context,GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)351 bool ValidateColorMaskiEXT(const Context *context,
352 GLuint index,
353 GLboolean r,
354 GLboolean g,
355 GLboolean b,
356 GLboolean a)
357 {
358 if (!context->getExtensions().drawBuffersIndexedEXT)
359 {
360 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
361 return false;
362 }
363
364 return ValidateColorMaski(context, index, r, g, b, a);
365 }
366
ValidateDisableiEXT(const Context * context,GLenum target,GLuint index)367 bool ValidateDisableiEXT(const Context *context, GLenum target, GLuint index)
368 {
369 if (!context->getExtensions().drawBuffersIndexedEXT)
370 {
371 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
372 return false;
373 }
374
375 return ValidateDisablei(context, target, index);
376 }
377
ValidateEnableiEXT(const Context * context,GLenum target,GLuint index)378 bool ValidateEnableiEXT(const Context *context, GLenum target, GLuint index)
379 {
380 if (!context->getExtensions().drawBuffersIndexedEXT)
381 {
382 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
383 return false;
384 }
385
386 return ValidateEnablei(context, target, index);
387 }
388
ValidateIsEnablediEXT(const Context * context,GLenum target,GLuint index)389 bool ValidateIsEnablediEXT(const Context *context, GLenum target, GLuint index)
390 {
391 if (!context->getExtensions().drawBuffersIndexedEXT)
392 {
393 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
394 return false;
395 }
396
397 return ValidateIsEnabledi(context, target, index);
398 }
399
ValidateBlendEquationSeparateiOES(const Context * context,GLuint buf,GLenum modeRGB,GLenum modeAlpha)400 bool ValidateBlendEquationSeparateiOES(const Context *context,
401 GLuint buf,
402 GLenum modeRGB,
403 GLenum modeAlpha)
404 {
405 if (!context->getExtensions().drawBuffersIndexedOES)
406 {
407 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
408 return false;
409 }
410
411 return ValidateBlendEquationSeparatei(context, buf, modeRGB, modeAlpha);
412 }
413
ValidateBlendEquationiOES(const Context * context,GLuint buf,GLenum mode)414 bool ValidateBlendEquationiOES(const Context *context, GLuint buf, GLenum mode)
415 {
416 if (!context->getExtensions().drawBuffersIndexedOES)
417 {
418 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
419 return false;
420 }
421
422 return ValidateBlendEquationi(context, buf, mode);
423 }
424
ValidateBlendFuncSeparateiOES(const Context * context,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)425 bool ValidateBlendFuncSeparateiOES(const Context *context,
426 GLuint buf,
427 GLenum srcRGB,
428 GLenum dstRGB,
429 GLenum srcAlpha,
430 GLenum dstAlpha)
431 {
432 if (!context->getExtensions().drawBuffersIndexedOES)
433 {
434 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
435 return false;
436 }
437
438 return ValidateBlendFuncSeparatei(context, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
439 }
440
ValidateBlendFunciOES(const Context * context,GLuint buf,GLenum src,GLenum dst)441 bool ValidateBlendFunciOES(const Context *context, GLuint buf, GLenum src, GLenum dst)
442 {
443 if (!context->getExtensions().drawBuffersIndexedOES)
444 {
445 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
446 return false;
447 }
448
449 return ValidateBlendFunci(context, buf, src, dst);
450 }
451
ValidateColorMaskiOES(const Context * context,GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)452 bool ValidateColorMaskiOES(const Context *context,
453 GLuint index,
454 GLboolean r,
455 GLboolean g,
456 GLboolean b,
457 GLboolean a)
458 {
459 if (!context->getExtensions().drawBuffersIndexedOES)
460 {
461 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
462 return false;
463 }
464
465 return ValidateColorMaski(context, index, r, g, b, a);
466 }
467
ValidateDisableiOES(const Context * context,GLenum target,GLuint index)468 bool ValidateDisableiOES(const Context *context, GLenum target, GLuint index)
469 {
470 if (!context->getExtensions().drawBuffersIndexedOES)
471 {
472 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
473 return false;
474 }
475
476 return ValidateDisablei(context, target, index);
477 }
478
ValidateEnableiOES(const Context * context,GLenum target,GLuint index)479 bool ValidateEnableiOES(const Context *context, GLenum target, GLuint index)
480 {
481 if (!context->getExtensions().drawBuffersIndexedOES)
482 {
483 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
484 return false;
485 }
486
487 return ValidateEnablei(context, target, index);
488 }
489
ValidateIsEnablediOES(const Context * context,GLenum target,GLuint index)490 bool ValidateIsEnablediOES(const Context *context, GLenum target, GLuint index)
491 {
492 if (!context->getExtensions().drawBuffersIndexedOES)
493 {
494 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
495 return false;
496 }
497
498 return ValidateIsEnabledi(context, target, index);
499 }
500
ValidateGetInteger64vEXT(const Context * context,GLenum pname,const GLint64 * data)501 bool ValidateGetInteger64vEXT(const Context *context, GLenum pname, const GLint64 *data)
502 {
503 if (!context->getExtensions().disjointTimerQuery)
504 {
505 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
506 return false;
507 }
508
509 GLenum nativeType = GL_NONE;
510 unsigned int numParams = 0;
511 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
512 {
513 return false;
514 }
515
516 return true;
517 }
518 } // namespace gl
519