1 //
2 // Copyright(c) 2014 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 // entry_points_gles_3_0.cpp : Implements the GLES 3.0 entry points.
8
9 #include "libGLESv2/entry_points_gles_3_0.h"
10 #include "libGLESv2/entry_points_gles_2_0_ext.h"
11 #include "libGLESv2/global_state.h"
12
13 #include "libANGLE/formatutils.h"
14 #include "libANGLE/Buffer.h"
15 #include "libANGLE/Context.h"
16 #include "libANGLE/Error.h"
17 #include "libANGLE/Fence.h"
18 #include "libANGLE/Framebuffer.h"
19 #include "libANGLE/Query.h"
20 #include "libANGLE/VertexArray.h"
21
22 #include "libANGLE/validationES.h"
23 #include "libANGLE/validationES3.h"
24 #include "libANGLE/queryconversions.h"
25 #include "libANGLE/queryutils.h"
26
27 #include "common/debug.h"
28
29 namespace gl
30 {
31
ReadBuffer(GLenum mode)32 void GL_APIENTRY ReadBuffer(GLenum mode)
33 {
34 EVENT("(GLenum mode = 0x%X)", mode);
35
36 Context *context = GetValidGlobalContext();
37 if (context)
38 {
39 if (!context->skipValidation() && !ValidateReadBuffer(context, mode))
40 {
41 return;
42 }
43
44 context->readBuffer(mode);
45 }
46 }
47
DrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices)48 void GL_APIENTRY DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices)
49 {
50 EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, "
51 "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices);
52
53 Context *context = GetValidGlobalContext();
54 if (context)
55 {
56 IndexRange indexRange;
57 if (!context->skipValidation() &&
58 !ValidateDrawRangeElements(context, mode, start, end, count, type, indices,
59 &indexRange))
60 {
61 return;
62 }
63
64 // As long as index validation is done, it doesn't matter whether the context receives a drawElements or
65 // a drawRangeElements call - the GL back-end is free to choose to call drawRangeElements based on the
66 // validated index range. If index validation is removed, adding drawRangeElements to the context interface
67 // should be reconsidered.
68 Error error =
69 context->drawRangeElements(mode, start, end, count, type, indices, indexRange);
70 if (error.isError())
71 {
72 context->handleError(error);
73 return;
74 }
75 }
76 }
77
TexImage3D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)78 void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
79 {
80 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, "
81 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, "
82 "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
83 target, level, internalformat, width, height, depth, border, format, type, pixels);
84
85 Context *context = GetValidGlobalContext();
86 if (context)
87 {
88 if (!context->skipValidation() &&
89 !ValidateTexImage3D(context, target, level, internalformat, width, height, depth,
90 border, format, type, pixels))
91 {
92 return;
93 }
94
95 context->texImage3D(target, level, internalformat, width, height, depth, border, format,
96 type, pixels);
97 }
98 }
99
TexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const GLvoid * pixels)100 void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
101 {
102 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
103 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
104 "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
105 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
106
107 Context *context = GetValidGlobalContext();
108 if (context)
109 {
110 if (!context->skipValidation() &&
111 !ValidateTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, width, height,
112 depth, format, type, pixels))
113 {
114 return;
115 }
116
117 context->texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth,
118 format, type, pixels);
119 }
120 }
121
CopyTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)122 void GL_APIENTRY CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
123 {
124 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
125 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
126 target, level, xoffset, yoffset, zoffset, x, y, width, height);
127
128 Context *context = GetValidGlobalContext();
129 if (context)
130 {
131 if (!context->skipValidation() &&
132 !ValidateCopyTexSubImage3D(context, target, level, xoffset, yoffset, zoffset, x, y,
133 width, height))
134 {
135 return;
136 }
137
138 context->copyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
139 }
140 }
141
CompressedTexImage3D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const GLvoid * data)142 void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
143 {
144 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
145 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, "
146 "const GLvoid* data = 0x%0.8p)",
147 target, level, internalformat, width, height, depth, border, imageSize, data);
148
149 Context *context = GetValidGlobalContext();
150 if (context)
151 {
152 if (!context->skipValidation() &&
153 !ValidateCompressedTexImage3D(context, target, level, internalformat, width, height,
154 depth, border, imageSize, data))
155 {
156 return;
157 }
158
159 context->compressedTexImage3D(target, level, internalformat, width, height, depth, border,
160 imageSize, data);
161 }
162 }
163
CompressedTexSubImage3D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const GLvoid * data)164 void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
165 {
166 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
167 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
168 "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
169 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
170
171 Context *context = GetValidGlobalContext();
172 if (context)
173 {
174 if (!context->skipValidation() &&
175 !ValidateCompressedTexSubImage3D(context, target, level, xoffset, yoffset, zoffset,
176 width, height, depth, format, imageSize, data))
177 {
178 return;
179 }
180
181 context->compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
182 depth, format, imageSize, data);
183 }
184 }
185
GenQueries(GLsizei n,GLuint * ids)186 void GL_APIENTRY GenQueries(GLsizei n, GLuint* ids)
187 {
188 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
189
190 Context *context = GetValidGlobalContext();
191 if (context)
192 {
193 if (!context->skipValidation() && !ValidateGenQueries(context, n, ids))
194 {
195 return;
196 }
197
198 for (GLsizei i = 0; i < n; i++)
199 {
200 ids[i] = context->createQuery();
201 }
202 }
203 }
204
DeleteQueries(GLsizei n,const GLuint * ids)205 void GL_APIENTRY DeleteQueries(GLsizei n, const GLuint* ids)
206 {
207 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
208
209 Context *context = GetValidGlobalContext();
210 if (context)
211 {
212 if (!context->skipValidation() && !ValidateDeleteQueries(context, n, ids))
213 {
214 return;
215 }
216
217 for (int i = 0; i < n; i++)
218 {
219 context->deleteQuery(ids[i]);
220 }
221 }
222 }
223
IsQuery(GLuint id)224 GLboolean GL_APIENTRY IsQuery(GLuint id)
225 {
226 EVENT("(GLuint id = %u)", id);
227
228 Context *context = GetValidGlobalContext();
229 if (context)
230 {
231 if (context->getClientMajorVersion() < 3)
232 {
233 context->handleError(Error(GL_INVALID_OPERATION));
234 return GL_FALSE;
235 }
236
237 return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE;
238 }
239
240 return GL_FALSE;
241 }
242
BeginQuery(GLenum target,GLuint id)243 void GL_APIENTRY BeginQuery(GLenum target, GLuint id)
244 {
245 EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
246
247 Context *context = GetValidGlobalContext();
248 if (context)
249 {
250 if (!ValidateBeginQuery(context, target, id))
251 {
252 return;
253 }
254
255 Error error = context->beginQuery(target, id);
256 if (error.isError())
257 {
258 context->handleError(error);
259 return;
260 }
261 }
262 }
263
EndQuery(GLenum target)264 void GL_APIENTRY EndQuery(GLenum target)
265 {
266 EVENT("(GLenum target = 0x%X)", target);
267
268 Context *context = GetValidGlobalContext();
269 if (context)
270 {
271 if (!ValidateEndQuery(context, target))
272 {
273 return;
274 }
275
276 Error error = context->endQuery(target);
277 if (error.isError())
278 {
279 context->handleError(error);
280 return;
281 }
282 }
283 }
284
GetQueryiv(GLenum target,GLenum pname,GLint * params)285 void GL_APIENTRY GetQueryiv(GLenum target, GLenum pname, GLint* params)
286 {
287 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
288
289 Context *context = GetValidGlobalContext();
290 if (context)
291 {
292 if (!ValidateGetQueryiv(context, target, pname, params))
293 {
294 return;
295 }
296
297 context->getQueryiv(target, pname, params);
298 }
299 }
300
GetQueryObjectuiv(GLuint id,GLenum pname,GLuint * params)301 void GL_APIENTRY GetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params)
302 {
303 EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params);
304
305 Context *context = GetValidGlobalContext();
306 if (context)
307 {
308 if (!ValidateGetQueryObjectuiv(context, id, pname, params))
309 {
310 return;
311 }
312
313 context->getQueryObjectuiv(id, pname, params);
314 }
315 }
316
UnmapBuffer(GLenum target)317 GLboolean GL_APIENTRY UnmapBuffer(GLenum target)
318 {
319 EVENT("(GLenum target = 0x%X)", target);
320
321 Context *context = GetValidGlobalContext();
322 if (context)
323 {
324 if (!context->skipValidation() && !ValidateUnmapBuffer(context, target))
325 {
326 return GL_FALSE;
327 }
328
329 return context->unmapBuffer(target);
330 }
331
332 return GL_FALSE;
333 }
334
GetBufferPointerv(GLenum target,GLenum pname,GLvoid ** params)335 void GL_APIENTRY GetBufferPointerv(GLenum target, GLenum pname, GLvoid** params)
336 {
337 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params);
338
339 Context *context = GetValidGlobalContext();
340 if (context)
341 {
342 if (!context->skipValidation() &&
343 !ValidateGetBufferPointerv(context, target, pname, params))
344 {
345 return;
346 }
347
348 context->getBufferPointerv(target, pname, params);
349 }
350 }
351
DrawBuffers(GLsizei n,const GLenum * bufs)352 void GL_APIENTRY DrawBuffers(GLsizei n, const GLenum* bufs)
353 {
354 Context *context = GetValidGlobalContext();
355 if (context)
356 {
357 if (!context->skipValidation() && !ValidateDrawBuffers(context, n, bufs))
358 {
359 return;
360 }
361
362 context->drawBuffers(n, bufs);
363 }
364 }
365
UniformMatrix2x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)366 void GL_APIENTRY UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
367 {
368 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
369 location, count, transpose, value);
370
371 Context *context = GetValidGlobalContext();
372 if (context)
373 {
374 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose))
375 {
376 return;
377 }
378
379 Program *program = context->getGLState().getProgram();
380 program->setUniformMatrix2x3fv(location, count, transpose, value);
381 }
382 }
383
UniformMatrix3x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)384 void GL_APIENTRY UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
385 {
386 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
387 location, count, transpose, value);
388
389 Context *context = GetValidGlobalContext();
390 if (context)
391 {
392 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose))
393 {
394 return;
395 }
396
397 Program *program = context->getGLState().getProgram();
398 program->setUniformMatrix3x2fv(location, count, transpose, value);
399 }
400 }
401
UniformMatrix2x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)402 void GL_APIENTRY UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
403 {
404 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
405 location, count, transpose, value);
406
407 Context *context = GetValidGlobalContext();
408 if (context)
409 {
410 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose))
411 {
412 return;
413 }
414
415 Program *program = context->getGLState().getProgram();
416 program->setUniformMatrix2x4fv(location, count, transpose, value);
417 }
418 }
419
UniformMatrix4x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)420 void GL_APIENTRY UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
421 {
422 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
423 location, count, transpose, value);
424
425 Context *context = GetValidGlobalContext();
426 if (context)
427 {
428 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose))
429 {
430 return;
431 }
432
433 Program *program = context->getGLState().getProgram();
434 program->setUniformMatrix4x2fv(location, count, transpose, value);
435 }
436 }
437
UniformMatrix3x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)438 void GL_APIENTRY UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
439 {
440 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
441 location, count, transpose, value);
442
443 Context *context = GetValidGlobalContext();
444 if (context)
445 {
446 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose))
447 {
448 return;
449 }
450
451 Program *program = context->getGLState().getProgram();
452 program->setUniformMatrix3x4fv(location, count, transpose, value);
453 }
454 }
455
UniformMatrix4x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)456 void GL_APIENTRY UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
457 {
458 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
459 location, count, transpose, value);
460
461 Context *context = GetValidGlobalContext();
462 if (context)
463 {
464 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose))
465 {
466 return;
467 }
468
469 Program *program = context->getGLState().getProgram();
470 program->setUniformMatrix4x3fv(location, count, transpose, value);
471 }
472 }
473
BlitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)474 void GL_APIENTRY BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
475 {
476 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, "
477 "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
478 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
479
480 Context *context = GetValidGlobalContext();
481 if (context)
482 {
483 if (!context->skipValidation() &&
484 !ValidateBlitFramebuffer(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1,
485 dstY1, mask, filter))
486 {
487 return;
488 }
489
490 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
491 filter);
492 }
493 }
494
RenderbufferStorageMultisample(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)495 void GL_APIENTRY RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
496 {
497 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
498 target, samples, internalformat, width, height);
499
500 Context *context = GetValidGlobalContext();
501 if (context)
502 {
503 if (context->getClientMajorVersion() < 3)
504 {
505 context->handleError(Error(GL_INVALID_OPERATION));
506 return;
507 }
508
509 if (!ValidateES3RenderbufferStorageParameters(context, target, samples, internalformat, width, height))
510 {
511 return;
512 }
513
514 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
515 renderbuffer->setStorageMultisample(samples, internalformat, width, height);
516 }
517 }
518
FramebufferTextureLayer(GLenum target,GLenum attachment,GLuint texture,GLint level,GLint layer)519 void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
520 {
521 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)",
522 target, attachment, texture, level, layer);
523
524 Context *context = GetValidGlobalContext();
525 if (context)
526 {
527 if (!context->skipValidation() &&
528 !ValidateFramebufferTextureLayer(context, target, attachment, texture, level, layer))
529 {
530 return;
531 }
532
533 context->framebufferTextureLayer(target, attachment, texture, level, layer);
534 }
535 }
536
MapBufferRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)537 GLvoid *GL_APIENTRY MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
538 {
539 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)",
540 target, offset, length, access);
541
542 Context *context = GetValidGlobalContext();
543 if (context)
544 {
545 if (!context->skipValidation() &&
546 !ValidateMapBufferRange(context, target, offset, length, access))
547 {
548 return nullptr;
549 }
550
551 return context->mapBufferRange(target, offset, length, access);
552 }
553
554 return nullptr;
555 }
556
FlushMappedBufferRange(GLenum target,GLintptr offset,GLsizeiptr length)557 void GL_APIENTRY FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
558 {
559 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length);
560
561 Context *context = GetValidGlobalContext();
562 if (context)
563 {
564 if (!context->skipValidation() &&
565 !ValidateFlushMappedBufferRange(context, target, offset, length))
566 {
567 return;
568 }
569
570 context->flushMappedBufferRange(target, offset, length);
571 }
572 }
573
BindVertexArray(GLuint array)574 void GL_APIENTRY BindVertexArray(GLuint array)
575 {
576 EVENT("(GLuint array = %u)", array);
577
578 Context *context = GetValidGlobalContext();
579 if (context)
580 {
581 if (!ValidateBindVertexArray(context, array))
582 {
583 return;
584 }
585
586 context->bindVertexArray(array);
587 }
588 }
589
DeleteVertexArrays(GLsizei n,const GLuint * arrays)590 void GL_APIENTRY DeleteVertexArrays(GLsizei n, const GLuint* arrays)
591 {
592 EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays);
593
594 Context *context = GetValidGlobalContext();
595 if (context)
596 {
597 if (!context->skipValidation() && !ValidateDeleteVertexArrays(context, n, arrays))
598 {
599 return;
600 }
601
602 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
603 {
604 if (arrays[arrayIndex] != 0)
605 {
606 context->deleteVertexArray(arrays[arrayIndex]);
607 }
608 }
609 }
610 }
611
GenVertexArrays(GLsizei n,GLuint * arrays)612 void GL_APIENTRY GenVertexArrays(GLsizei n, GLuint* arrays)
613 {
614 EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays);
615
616 Context *context = GetValidGlobalContext();
617 if (context)
618 {
619 if (!context->skipValidation() && !ValidateGenVertexArrays(context, n, arrays))
620 {
621 return;
622 }
623
624 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
625 {
626 arrays[arrayIndex] = context->createVertexArray();
627 }
628 }
629 }
630
IsVertexArray(GLuint array)631 GLboolean GL_APIENTRY IsVertexArray(GLuint array)
632 {
633 EVENT("(GLuint array = %u)", array);
634
635 Context *context = GetValidGlobalContext();
636 if (context)
637 {
638 if (!ValidateIsVertexArray(context))
639 {
640 return GL_FALSE;
641 }
642
643 if (array == 0)
644 {
645 return GL_FALSE;
646 }
647
648 VertexArray *vao = context->getVertexArray(array);
649
650 return (vao != NULL ? GL_TRUE : GL_FALSE);
651 }
652
653 return GL_FALSE;
654 }
655
GetIntegeri_v(GLenum target,GLuint index,GLint * data)656 void GL_APIENTRY GetIntegeri_v(GLenum target, GLuint index, GLint *data)
657 {
658 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)",
659 target, index, data);
660
661 Context *context = GetValidGlobalContext();
662 if (context)
663 {
664 if (!context->skipValidation() && !ValidateGetIntegeri_v(context, target, index, data))
665 {
666 return;
667 }
668 context->getIntegeri_v(target, index, data);
669 }
670 }
671
BeginTransformFeedback(GLenum primitiveMode)672 void GL_APIENTRY BeginTransformFeedback(GLenum primitiveMode)
673 {
674 EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode);
675
676 Context *context = GetValidGlobalContext();
677 if (context)
678 {
679 if (!context->skipValidation() && !ValidateBeginTransformFeedback(context, primitiveMode))
680 {
681 return;
682 }
683
684 context->beginTransformFeedback(primitiveMode);
685 }
686 }
687
EndTransformFeedback(void)688 void GL_APIENTRY EndTransformFeedback(void)
689 {
690 EVENT("(void)");
691
692 Context *context = GetValidGlobalContext();
693 if (context)
694 {
695 if (context->getClientMajorVersion() < 3)
696 {
697 context->handleError(Error(GL_INVALID_OPERATION));
698 return;
699 }
700
701 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
702 ASSERT(transformFeedback != NULL);
703
704 if (!transformFeedback->isActive())
705 {
706 context->handleError(Error(GL_INVALID_OPERATION));
707 return;
708 }
709
710 transformFeedback->end();
711 }
712 }
713
BindBufferRange(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)714 void GL_APIENTRY BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
715 {
716 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)",
717 target, index, buffer, offset, size);
718
719 Context *context = GetValidGlobalContext();
720 if (context)
721 {
722 if (context->getClientMajorVersion() < 3)
723 {
724 context->handleError(Error(GL_INVALID_OPERATION));
725 return;
726 }
727
728 const Caps &caps = context->getCaps();
729 switch (target)
730 {
731 case GL_TRANSFORM_FEEDBACK_BUFFER:
732 if (index >= caps.maxTransformFeedbackSeparateAttributes)
733 {
734 context->handleError(Error(GL_INVALID_VALUE));
735 return;
736 }
737 break;
738
739 case GL_UNIFORM_BUFFER:
740 if (index >= caps.maxUniformBufferBindings)
741 {
742 context->handleError(Error(GL_INVALID_VALUE));
743 return;
744 }
745 break;
746
747 default:
748 context->handleError(Error(GL_INVALID_ENUM));
749 return;
750 }
751
752 if (buffer != 0 && size <= 0)
753 {
754 context->handleError(Error(GL_INVALID_VALUE));
755 return;
756 }
757
758 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
759 !context->isBufferGenerated(buffer))
760 {
761 context->handleError(Error(GL_INVALID_OPERATION, "Buffer was not generated"));
762 return;
763 }
764
765 switch (target)
766 {
767 case GL_TRANSFORM_FEEDBACK_BUFFER:
768 {
769 // size and offset must be a multiple of 4
770 if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0))
771 {
772 context->handleError(Error(GL_INVALID_VALUE));
773 return;
774 }
775
776 // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2)
777 TransformFeedback *curTransformFeedback =
778 context->getGLState().getCurrentTransformFeedback();
779 if (curTransformFeedback && curTransformFeedback->isActive())
780 {
781 context->handleError(Error(GL_INVALID_OPERATION));
782 return;
783 }
784
785 context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size);
786 context->bindGenericTransformFeedbackBuffer(buffer);
787 break;
788 }
789
790 case GL_UNIFORM_BUFFER:
791
792 // it is an error to bind an offset not a multiple of the alignment
793 if (buffer != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
794 {
795 context->handleError(Error(GL_INVALID_VALUE));
796 return;
797 }
798
799 context->bindIndexedUniformBuffer(buffer, index, offset, size);
800 context->bindGenericUniformBuffer(buffer);
801 break;
802
803 default:
804 UNREACHABLE();
805 }
806 }
807 }
808
BindBufferBase(GLenum target,GLuint index,GLuint buffer)809 void GL_APIENTRY BindBufferBase(GLenum target, GLuint index, GLuint buffer)
810 {
811 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)",
812 target, index, buffer);
813
814 Context *context = GetValidGlobalContext();
815 if (context)
816 {
817 if (context->getClientMajorVersion() < 3)
818 {
819 context->handleError(Error(GL_INVALID_OPERATION));
820 return;
821 }
822
823 const Caps &caps = context->getCaps();
824 switch (target)
825 {
826 case GL_TRANSFORM_FEEDBACK_BUFFER:
827 if (index >= caps.maxTransformFeedbackSeparateAttributes)
828 {
829 context->handleError(Error(GL_INVALID_VALUE));
830 return;
831 }
832 break;
833
834 case GL_UNIFORM_BUFFER:
835 if (index >= caps.maxUniformBufferBindings)
836 {
837 context->handleError(Error(GL_INVALID_VALUE));
838 return;
839 }
840 break;
841
842 default:
843 context->handleError(Error(GL_INVALID_ENUM));
844 return;
845 }
846
847 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
848 !context->isBufferGenerated(buffer))
849 {
850 context->handleError(Error(GL_INVALID_OPERATION, "Buffer was not generated"));
851 return;
852 }
853
854 switch (target)
855 {
856 case GL_TRANSFORM_FEEDBACK_BUFFER:
857 {
858 // Cannot bind a transform feedback buffer if the current transform feedback is active (3.0.4 pg 91 section 2.15.2)
859 TransformFeedback *curTransformFeedback =
860 context->getGLState().getCurrentTransformFeedback();
861 if (curTransformFeedback && curTransformFeedback->isActive())
862 {
863 context->handleError(Error(GL_INVALID_OPERATION));
864 return;
865 }
866
867 context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0);
868 context->bindGenericTransformFeedbackBuffer(buffer);
869 break;
870 }
871 case GL_UNIFORM_BUFFER:
872 context->bindIndexedUniformBuffer(buffer, index, 0, 0);
873 context->bindGenericUniformBuffer(buffer);
874 break;
875
876 default:
877 UNREACHABLE();
878 }
879 }
880 }
881
TransformFeedbackVaryings(GLuint program,GLsizei count,const GLchar * const * varyings,GLenum bufferMode)882 void GL_APIENTRY TransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
883 {
884 EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)",
885 program, count, varyings, bufferMode);
886
887 Context *context = GetValidGlobalContext();
888 if (context)
889 {
890 if (context->getClientMajorVersion() < 3)
891 {
892 context->handleError(Error(GL_INVALID_OPERATION));
893 return;
894 }
895
896 if (count < 0)
897 {
898 context->handleError(Error(GL_INVALID_VALUE));
899 return;
900 }
901
902 const Caps &caps = context->getCaps();
903 switch (bufferMode)
904 {
905 case GL_INTERLEAVED_ATTRIBS:
906 break;
907 case GL_SEPARATE_ATTRIBS:
908 if (static_cast<GLuint>(count) > caps.maxTransformFeedbackSeparateAttributes)
909 {
910 context->handleError(Error(GL_INVALID_VALUE));
911 return;
912 }
913 break;
914 default:
915 context->handleError(Error(GL_INVALID_ENUM));
916 return;
917 }
918
919 Program *programObject = GetValidProgram(context, program);
920 if (!programObject)
921 {
922 return;
923 }
924
925 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
926 }
927 }
928
GetTransformFeedbackVarying(GLuint program,GLuint index,GLsizei bufSize,GLsizei * length,GLsizei * size,GLenum * type,GLchar * name)929 void GL_APIENTRY GetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
930 {
931 EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, "
932 "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
933 program, index, bufSize, length, size, type, name);
934
935 Context *context = GetValidGlobalContext();
936 if (context)
937 {
938 if (context->getClientMajorVersion() < 3)
939 {
940 context->handleError(Error(GL_INVALID_OPERATION));
941 return;
942 }
943
944 if (bufSize < 0)
945 {
946 context->handleError(Error(GL_INVALID_VALUE));
947 return;
948 }
949
950 Program *programObject = GetValidProgram(context, program);
951 if (!programObject)
952 {
953 return;
954 }
955
956 if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
957 {
958 context->handleError(Error(GL_INVALID_VALUE));
959 return;
960 }
961
962 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
963 }
964 }
965
VertexAttribIPointer(GLuint index,GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)966 void GL_APIENTRY VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer)
967 {
968 EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)",
969 index, size, type, stride, pointer);
970
971 Context *context = GetValidGlobalContext();
972 if (context)
973 {
974 if (context->getClientMajorVersion() < 3)
975 {
976 context->handleError(Error(GL_INVALID_OPERATION));
977 return;
978 }
979
980 if (index >= MAX_VERTEX_ATTRIBS)
981 {
982 context->handleError(Error(GL_INVALID_VALUE));
983 return;
984 }
985
986 if (size < 1 || size > 4)
987 {
988 context->handleError(Error(GL_INVALID_VALUE));
989 return;
990 }
991
992 switch (type)
993 {
994 case GL_BYTE:
995 case GL_UNSIGNED_BYTE:
996 case GL_SHORT:
997 case GL_UNSIGNED_SHORT:
998 case GL_INT:
999 case GL_UNSIGNED_INT:
1000 break;
1001
1002 default:
1003 context->handleError(Error(GL_INVALID_ENUM));
1004 return;
1005 }
1006
1007 if (stride < 0)
1008 {
1009 context->handleError(Error(GL_INVALID_VALUE));
1010 return;
1011 }
1012
1013 // [OpenGL ES 3.0.2] Section 2.8 page 24:
1014 // An INVALID_OPERATION error is generated when a non-zero vertex array object
1015 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
1016 // and the pointer argument is not NULL.
1017 if (context->getGLState().getVertexArray()->id() != 0 &&
1018 context->getGLState().getArrayBufferId() == 0 && pointer != NULL)
1019 {
1020 context->handleError(Error(GL_INVALID_OPERATION));
1021 return;
1022 }
1023
1024 context->vertexAttribIPointer(index, size, type, stride, pointer);
1025 }
1026 }
1027
GetVertexAttribIiv(GLuint index,GLenum pname,GLint * params)1028 void GL_APIENTRY GetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
1029 {
1030 EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1031 index, pname, params);
1032
1033 Context *context = GetValidGlobalContext();
1034 if (context)
1035 {
1036 if (!context->skipValidation() &&
1037 !ValidateGetVertexAttribIiv(context, index, pname, params))
1038 {
1039 return;
1040 }
1041
1042 const VertexAttribCurrentValueData ¤tValues =
1043 context->getGLState().getVertexAttribCurrentValue(index);
1044 const VertexAttribute &attrib =
1045 context->getGLState().getVertexArray()->getVertexAttribute(index);
1046 QueryVertexAttribIiv(attrib, currentValues, pname, params);
1047 }
1048 }
1049
GetVertexAttribIuiv(GLuint index,GLenum pname,GLuint * params)1050 void GL_APIENTRY GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
1051 {
1052 EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)",
1053 index, pname, params);
1054
1055 Context *context = GetValidGlobalContext();
1056 if (context)
1057 {
1058 if (!context->skipValidation() &&
1059 !ValidateGetVertexAttribIuiv(context, index, pname, params))
1060 {
1061 return;
1062 }
1063
1064 const VertexAttribCurrentValueData ¤tValues =
1065 context->getGLState().getVertexAttribCurrentValue(index);
1066 const VertexAttribute &attrib =
1067 context->getGLState().getVertexArray()->getVertexAttribute(index);
1068 QueryVertexAttribIuiv(attrib, currentValues, pname, params);
1069 }
1070 }
1071
VertexAttribI4i(GLuint index,GLint x,GLint y,GLint z,GLint w)1072 void GL_APIENTRY VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
1073 {
1074 EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)",
1075 index, x, y, z, w);
1076
1077 Context *context = GetValidGlobalContext();
1078 if (context)
1079 {
1080 if (context->getClientMajorVersion() < 3)
1081 {
1082 context->handleError(Error(GL_INVALID_OPERATION));
1083 return;
1084 }
1085
1086 if (index >= MAX_VERTEX_ATTRIBS)
1087 {
1088 context->handleError(Error(GL_INVALID_VALUE));
1089 return;
1090 }
1091
1092 context->vertexAttribI4i(index, x, y, z, w);
1093 }
1094 }
1095
VertexAttribI4ui(GLuint index,GLuint x,GLuint y,GLuint z,GLuint w)1096 void GL_APIENTRY VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
1097 {
1098 EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)",
1099 index, x, y, z, w);
1100
1101 Context *context = GetValidGlobalContext();
1102 if (context)
1103 {
1104 if (context->getClientMajorVersion() < 3)
1105 {
1106 context->handleError(Error(GL_INVALID_OPERATION));
1107 return;
1108 }
1109
1110 if (index >= MAX_VERTEX_ATTRIBS)
1111 {
1112 context->handleError(Error(GL_INVALID_VALUE));
1113 return;
1114 }
1115
1116 context->vertexAttribI4ui(index, x, y, z, w);
1117 }
1118 }
1119
VertexAttribI4iv(GLuint index,const GLint * v)1120 void GL_APIENTRY VertexAttribI4iv(GLuint index, const GLint* v)
1121 {
1122 EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v);
1123
1124 Context *context = GetValidGlobalContext();
1125 if (context)
1126 {
1127 if (context->getClientMajorVersion() < 3)
1128 {
1129 context->handleError(Error(GL_INVALID_OPERATION));
1130 return;
1131 }
1132
1133 if (index >= MAX_VERTEX_ATTRIBS)
1134 {
1135 context->handleError(Error(GL_INVALID_VALUE));
1136 return;
1137 }
1138
1139 context->vertexAttribI4iv(index, v);
1140 }
1141 }
1142
VertexAttribI4uiv(GLuint index,const GLuint * v)1143 void GL_APIENTRY VertexAttribI4uiv(GLuint index, const GLuint* v)
1144 {
1145 EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v);
1146
1147 Context *context = GetValidGlobalContext();
1148 if (context)
1149 {
1150 if (context->getClientMajorVersion() < 3)
1151 {
1152 context->handleError(Error(GL_INVALID_OPERATION));
1153 return;
1154 }
1155
1156 if (index >= MAX_VERTEX_ATTRIBS)
1157 {
1158 context->handleError(Error(GL_INVALID_VALUE));
1159 return;
1160 }
1161
1162 context->vertexAttribI4uiv(index, v);
1163 }
1164 }
1165
GetUniformuiv(GLuint program,GLint location,GLuint * params)1166 void GL_APIENTRY GetUniformuiv(GLuint program, GLint location, GLuint* params)
1167 {
1168 EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)",
1169 program, location, params);
1170
1171 Context *context = GetValidGlobalContext();
1172 if (context)
1173 {
1174 if (!ValidateGetUniformuiv(context, program, location, params))
1175 {
1176 return;
1177 }
1178
1179 Program *programObject = context->getProgram(program);
1180 ASSERT(programObject);
1181
1182 programObject->getUniformuiv(location, params);
1183 }
1184 }
1185
GetFragDataLocation(GLuint program,const GLchar * name)1186 GLint GL_APIENTRY GetFragDataLocation(GLuint program, const GLchar *name)
1187 {
1188 EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)",
1189 program, name);
1190
1191 Context *context = GetValidGlobalContext();
1192 if (context)
1193 {
1194 if (context->getClientMajorVersion() < 3)
1195 {
1196 context->handleError(Error(GL_INVALID_OPERATION));
1197 return -1;
1198 }
1199
1200 if (program == 0)
1201 {
1202 context->handleError(Error(GL_INVALID_VALUE));
1203 return -1;
1204 }
1205
1206 Program *programObject = context->getProgram(program);
1207
1208 if (!programObject || !programObject->isLinked())
1209 {
1210 context->handleError(Error(GL_INVALID_OPERATION));
1211 return -1;
1212 }
1213
1214 return programObject->getFragDataLocation(name);
1215 }
1216
1217 return 0;
1218 }
1219
Uniform1ui(GLint location,GLuint v0)1220 void GL_APIENTRY Uniform1ui(GLint location, GLuint v0)
1221 {
1222 Uniform1uiv(location, 1, &v0);
1223 }
1224
Uniform2ui(GLint location,GLuint v0,GLuint v1)1225 void GL_APIENTRY Uniform2ui(GLint location, GLuint v0, GLuint v1)
1226 {
1227 const GLuint xy[] = { v0, v1 };
1228 Uniform2uiv(location, 1, xy);
1229 }
1230
Uniform3ui(GLint location,GLuint v0,GLuint v1,GLuint v2)1231 void GL_APIENTRY Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
1232 {
1233 const GLuint xyz[] = { v0, v1, v2 };
1234 Uniform3uiv(location, 1, xyz);
1235 }
1236
Uniform4ui(GLint location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)1237 void GL_APIENTRY Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
1238 {
1239 const GLuint xyzw[] = { v0, v1, v2, v3 };
1240 Uniform4uiv(location, 1, xyzw);
1241 }
1242
Uniform1uiv(GLint location,GLsizei count,const GLuint * value)1243 void GL_APIENTRY Uniform1uiv(GLint location, GLsizei count, const GLuint* value)
1244 {
1245 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
1246 location, count, value);
1247
1248 Context *context = GetValidGlobalContext();
1249 if (context)
1250 {
1251 if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count))
1252 {
1253 return;
1254 }
1255
1256 Program *program = context->getGLState().getProgram();
1257 program->setUniform1uiv(location, count, value);
1258 }
1259 }
1260
Uniform2uiv(GLint location,GLsizei count,const GLuint * value)1261 void GL_APIENTRY Uniform2uiv(GLint location, GLsizei count, const GLuint* value)
1262 {
1263 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
1264 location, count, value);
1265
1266 Context *context = GetValidGlobalContext();
1267 if (context)
1268 {
1269 if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count))
1270 {
1271 return;
1272 }
1273
1274 Program *program = context->getGLState().getProgram();
1275 program->setUniform2uiv(location, count, value);
1276 }
1277 }
1278
Uniform3uiv(GLint location,GLsizei count,const GLuint * value)1279 void GL_APIENTRY Uniform3uiv(GLint location, GLsizei count, const GLuint* value)
1280 {
1281 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)",
1282 location, count, value);
1283
1284 Context *context = GetValidGlobalContext();
1285 if (context)
1286 {
1287 if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count))
1288 {
1289 return;
1290 }
1291
1292 Program *program = context->getGLState().getProgram();
1293 program->setUniform3uiv(location, count, value);
1294 }
1295 }
1296
Uniform4uiv(GLint location,GLsizei count,const GLuint * value)1297 void GL_APIENTRY Uniform4uiv(GLint location, GLsizei count, const GLuint* value)
1298 {
1299 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)",
1300 location, count, value);
1301
1302 Context *context = GetValidGlobalContext();
1303 if (context)
1304 {
1305 if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count))
1306 {
1307 return;
1308 }
1309
1310 Program *program = context->getGLState().getProgram();
1311 program->setUniform4uiv(location, count, value);
1312 }
1313 }
1314
ClearBufferiv(GLenum buffer,GLint drawbuffer,const GLint * value)1315 void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value)
1316 {
1317 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)",
1318 buffer, drawbuffer, value);
1319
1320 Context *context = GetValidGlobalContext();
1321 if (context)
1322 {
1323 if (!context->skipValidation() &&
1324 !ValidateClearBufferiv(context, buffer, drawbuffer, value))
1325 {
1326 return;
1327 }
1328
1329 context->clearBufferiv(buffer, drawbuffer, value);
1330 }
1331 }
1332
ClearBufferuiv(GLenum buffer,GLint drawbuffer,const GLuint * value)1333 void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value)
1334 {
1335 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)",
1336 buffer, drawbuffer, value);
1337
1338 Context *context = GetValidGlobalContext();
1339 if (context)
1340 {
1341 if (!context->skipValidation() &&
1342 !ValidateClearBufferuiv(context, buffer, drawbuffer, value))
1343 {
1344 return;
1345 }
1346
1347 context->clearBufferuiv(buffer, drawbuffer, value);
1348 }
1349 }
1350
ClearBufferfv(GLenum buffer,GLint drawbuffer,const GLfloat * value)1351 void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value)
1352 {
1353 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)",
1354 buffer, drawbuffer, value);
1355
1356 Context *context = GetValidGlobalContext();
1357 if (context)
1358 {
1359 if (!context->skipValidation() &&
1360 !ValidateClearBufferfv(context, buffer, drawbuffer, value))
1361 {
1362 return;
1363 }
1364
1365 context->clearBufferfv(buffer, drawbuffer, value);
1366 }
1367 }
1368
ClearBufferfi(GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)1369 void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
1370 {
1371 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)",
1372 buffer, drawbuffer, depth, stencil);
1373
1374 Context *context = GetValidGlobalContext();
1375 if (context)
1376 {
1377 if (!context->skipValidation() &&
1378 !ValidateClearBufferfi(context, buffer, drawbuffer, depth, stencil))
1379 {
1380 return;
1381 }
1382
1383 context->clearBufferfi(buffer, drawbuffer, depth, stencil);
1384 }
1385 }
1386
GetStringi(GLenum name,GLuint index)1387 const GLubyte *GL_APIENTRY GetStringi(GLenum name, GLuint index)
1388 {
1389 EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index);
1390
1391 Context *context = GetValidGlobalContext();
1392 if (context)
1393 {
1394 if (context->getClientMajorVersion() < 3)
1395 {
1396 context->handleError(Error(GL_INVALID_OPERATION));
1397 return NULL;
1398 }
1399
1400 if (name != GL_EXTENSIONS)
1401 {
1402 context->handleError(Error(GL_INVALID_ENUM));
1403 return NULL;
1404 }
1405
1406 if (index >= context->getExtensionStringCount())
1407 {
1408 context->handleError(Error(GL_INVALID_VALUE));
1409 return NULL;
1410 }
1411
1412 return reinterpret_cast<const GLubyte *>(context->getExtensionString(index));
1413 }
1414
1415 return NULL;
1416 }
1417
CopyBufferSubData(GLenum readTarget,GLenum writeTarget,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)1418 void GL_APIENTRY CopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
1419 {
1420 EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)",
1421 readTarget, writeTarget, readOffset, writeOffset, size);
1422
1423 Context *context = GetValidGlobalContext();
1424 if (context)
1425 {
1426 if (!context->skipValidation() &&
1427 !ValidateCopyBufferSubData(context, readTarget, writeTarget, readOffset, writeOffset,
1428 size))
1429 {
1430 return;
1431 }
1432
1433 context->copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
1434 }
1435 }
1436
GetUniformIndices(GLuint program,GLsizei uniformCount,const GLchar * const * uniformNames,GLuint * uniformIndices)1437 void GL_APIENTRY GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices)
1438 {
1439 EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)",
1440 program, uniformCount, uniformNames, uniformIndices);
1441
1442 Context *context = GetValidGlobalContext();
1443 if (context)
1444 {
1445 if (context->getClientMajorVersion() < 3)
1446 {
1447 context->handleError(Error(GL_INVALID_OPERATION));
1448 return;
1449 }
1450
1451 if (uniformCount < 0)
1452 {
1453 context->handleError(Error(GL_INVALID_VALUE));
1454 return;
1455 }
1456
1457 Program *programObject = GetValidProgram(context, program);
1458
1459 if (!programObject)
1460 {
1461 return;
1462 }
1463
1464 if (!programObject->isLinked())
1465 {
1466 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
1467 {
1468 uniformIndices[uniformId] = GL_INVALID_INDEX;
1469 }
1470 }
1471 else
1472 {
1473 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
1474 {
1475 uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
1476 }
1477 }
1478 }
1479 }
1480
GetActiveUniformsiv(GLuint program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,GLint * params)1481 void GL_APIENTRY GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
1482 {
1483 EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1484 program, uniformCount, uniformIndices, pname, params);
1485
1486 Context *context = GetValidGlobalContext();
1487 if (context)
1488 {
1489 if (context->getClientMajorVersion() < 3)
1490 {
1491 context->handleError(Error(GL_INVALID_OPERATION));
1492 return;
1493 }
1494
1495 if (uniformCount < 0)
1496 {
1497 context->handleError(Error(GL_INVALID_VALUE));
1498 return;
1499 }
1500
1501 Program *programObject = GetValidProgram(context, program);
1502
1503 if (!programObject)
1504 {
1505 return;
1506 }
1507
1508 switch (pname)
1509 {
1510 case GL_UNIFORM_TYPE:
1511 case GL_UNIFORM_SIZE:
1512 case GL_UNIFORM_NAME_LENGTH:
1513 case GL_UNIFORM_BLOCK_INDEX:
1514 case GL_UNIFORM_OFFSET:
1515 case GL_UNIFORM_ARRAY_STRIDE:
1516 case GL_UNIFORM_MATRIX_STRIDE:
1517 case GL_UNIFORM_IS_ROW_MAJOR:
1518 break;
1519
1520 default:
1521 context->handleError(Error(GL_INVALID_ENUM));
1522 return;
1523 }
1524
1525 if (uniformCount > programObject->getActiveUniformCount())
1526 {
1527 context->handleError(Error(GL_INVALID_VALUE));
1528 return;
1529 }
1530
1531 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
1532 {
1533 const GLuint index = uniformIndices[uniformId];
1534
1535 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
1536 {
1537 context->handleError(Error(GL_INVALID_VALUE));
1538 return;
1539 }
1540 }
1541
1542 for (int uniformId = 0; uniformId < uniformCount; uniformId++)
1543 {
1544 const GLuint index = uniformIndices[uniformId];
1545 params[uniformId] = programObject->getActiveUniformi(index, pname);
1546 }
1547 }
1548 }
1549
GetUniformBlockIndex(GLuint program,const GLchar * uniformBlockName)1550 GLuint GL_APIENTRY GetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName)
1551 {
1552 EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName);
1553
1554 Context *context = GetValidGlobalContext();
1555 if (context)
1556 {
1557 if (context->getClientMajorVersion() < 3)
1558 {
1559 context->handleError(Error(GL_INVALID_OPERATION));
1560 return GL_INVALID_INDEX;
1561 }
1562
1563 Program *programObject = GetValidProgram(context, program);
1564 if (!programObject)
1565 {
1566 return GL_INVALID_INDEX;
1567 }
1568
1569 return programObject->getUniformBlockIndex(uniformBlockName);
1570 }
1571
1572 return 0;
1573 }
1574
GetActiveUniformBlockiv(GLuint program,GLuint uniformBlockIndex,GLenum pname,GLint * params)1575 void GL_APIENTRY GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params)
1576 {
1577 EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1578 program, uniformBlockIndex, pname, params);
1579
1580 Context *context = GetValidGlobalContext();
1581 if (context)
1582 {
1583 if (!context->skipValidation() &&
1584 !ValidateGetActiveUniformBlockiv(context, program, uniformBlockIndex, pname, params))
1585 {
1586 return;
1587 }
1588
1589 const Program *programObject = context->getProgram(program);
1590 QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
1591 }
1592 }
1593
GetActiveUniformBlockName(GLuint program,GLuint uniformBlockIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformBlockName)1594 void GL_APIENTRY GetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName)
1595 {
1596 EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)",
1597 program, uniformBlockIndex, bufSize, length, uniformBlockName);
1598
1599 Context *context = GetValidGlobalContext();
1600 if (context)
1601 {
1602 if (context->getClientMajorVersion() < 3)
1603 {
1604 context->handleError(Error(GL_INVALID_OPERATION));
1605 return;
1606 }
1607
1608 Program *programObject = GetValidProgram(context, program);
1609
1610 if (!programObject)
1611 {
1612 return;
1613 }
1614
1615 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
1616 {
1617 context->handleError(Error(GL_INVALID_VALUE));
1618 return;
1619 }
1620
1621 programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
1622 }
1623 }
1624
UniformBlockBinding(GLuint program,GLuint uniformBlockIndex,GLuint uniformBlockBinding)1625 void GL_APIENTRY UniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
1626 {
1627 EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)",
1628 program, uniformBlockIndex, uniformBlockBinding);
1629
1630 Context *context = GetValidGlobalContext();
1631 if (context)
1632 {
1633 if (context->getClientMajorVersion() < 3)
1634 {
1635 context->handleError(Error(GL_INVALID_OPERATION));
1636 return;
1637 }
1638
1639 if (uniformBlockBinding >= context->getCaps().maxUniformBufferBindings)
1640 {
1641 context->handleError(Error(GL_INVALID_VALUE));
1642 return;
1643 }
1644
1645 Program *programObject = GetValidProgram(context, program);
1646
1647 if (!programObject)
1648 {
1649 return;
1650 }
1651
1652 // if never linked, there won't be any uniform blocks
1653 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
1654 {
1655 context->handleError(Error(GL_INVALID_VALUE));
1656 return;
1657 }
1658
1659 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
1660 }
1661 }
1662
DrawArraysInstanced(GLenum mode,GLint first,GLsizei count,GLsizei instanceCount)1663 void GL_APIENTRY DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
1664 {
1665 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",
1666 mode, first, count, instanceCount);
1667
1668 Context *context = GetValidGlobalContext();
1669 if (context)
1670 {
1671 if (context->getClientMajorVersion() < 3)
1672 {
1673 context->handleError(Error(GL_INVALID_OPERATION));
1674 return;
1675 }
1676
1677 if (!ValidateDrawArraysInstanced(context, mode, first, count, instanceCount))
1678 {
1679 return;
1680 }
1681
1682 Error error = context->drawArraysInstanced(mode, first, count, instanceCount);
1683 if (error.isError())
1684 {
1685 context->handleError(error);
1686 return;
1687 }
1688 }
1689 }
1690
DrawElementsInstanced(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices,GLsizei instanceCount)1691 void GL_APIENTRY DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount)
1692 {
1693 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)",
1694 mode, count, type, indices, instanceCount);
1695
1696 Context *context = GetValidGlobalContext();
1697 if (context)
1698 {
1699 if (context->getClientMajorVersion() < 3)
1700 {
1701 context->handleError(Error(GL_INVALID_OPERATION));
1702 return;
1703 }
1704
1705 IndexRange indexRange;
1706 if (!ValidateDrawElementsInstanced(context, mode, count, type, indices, instanceCount, &indexRange))
1707 {
1708 return;
1709 }
1710
1711 Error error =
1712 context->drawElementsInstanced(mode, count, type, indices, instanceCount, indexRange);
1713 if (error.isError())
1714 {
1715 context->handleError(error);
1716 return;
1717 }
1718 }
1719 }
1720
FenceSync_(GLenum condition,GLbitfield flags)1721 GLsync GL_APIENTRY FenceSync_(GLenum condition, GLbitfield flags)
1722 {
1723 EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags);
1724
1725 Context *context = GetValidGlobalContext();
1726 if (context)
1727 {
1728 if (context->getClientMajorVersion() < 3)
1729 {
1730 context->handleError(Error(GL_INVALID_OPERATION));
1731 return 0;
1732 }
1733
1734 if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
1735 {
1736 context->handleError(Error(GL_INVALID_ENUM));
1737 return 0;
1738 }
1739
1740 if (flags != 0)
1741 {
1742 context->handleError(Error(GL_INVALID_VALUE));
1743 return 0;
1744 }
1745
1746 GLsync fenceSync = context->createFenceSync();
1747
1748 FenceSync *fenceSyncObject = context->getFenceSync(fenceSync);
1749 Error error = fenceSyncObject->set(condition, flags);
1750 if (error.isError())
1751 {
1752 context->deleteFenceSync(fenceSync);
1753 context->handleError(error);
1754 return NULL;
1755 }
1756
1757 return fenceSync;
1758 }
1759
1760 return NULL;
1761 }
1762
IsSync(GLsync sync)1763 GLboolean GL_APIENTRY IsSync(GLsync sync)
1764 {
1765 EVENT("(GLsync sync = 0x%0.8p)", sync);
1766
1767 Context *context = GetValidGlobalContext();
1768 if (context)
1769 {
1770 if (context->getClientMajorVersion() < 3)
1771 {
1772 context->handleError(Error(GL_INVALID_OPERATION));
1773 return GL_FALSE;
1774 }
1775
1776 return (context->getFenceSync(sync) != NULL);
1777 }
1778
1779 return GL_FALSE;
1780 }
1781
DeleteSync(GLsync sync)1782 void GL_APIENTRY DeleteSync(GLsync sync)
1783 {
1784 EVENT("(GLsync sync = 0x%0.8p)", sync);
1785
1786 Context *context = GetValidGlobalContext();
1787 if (context)
1788 {
1789 if (context->getClientMajorVersion() < 3)
1790 {
1791 context->handleError(Error(GL_INVALID_OPERATION));
1792 return;
1793 }
1794
1795 if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync))
1796 {
1797 context->handleError(Error(GL_INVALID_VALUE));
1798 return;
1799 }
1800
1801 context->deleteFenceSync(sync);
1802 }
1803 }
1804
ClientWaitSync(GLsync sync,GLbitfield flags,GLuint64 timeout)1805 GLenum GL_APIENTRY ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
1806 {
1807 EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
1808 sync, flags, timeout);
1809
1810 Context *context = GetValidGlobalContext();
1811 if (context)
1812 {
1813 if (context->getClientMajorVersion() < 3)
1814 {
1815 context->handleError(Error(GL_INVALID_OPERATION));
1816 return GL_WAIT_FAILED;
1817 }
1818
1819 if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
1820 {
1821 context->handleError(Error(GL_INVALID_VALUE));
1822 return GL_WAIT_FAILED;
1823 }
1824
1825 FenceSync *fenceSync = context->getFenceSync(sync);
1826
1827 if (!fenceSync)
1828 {
1829 context->handleError(Error(GL_INVALID_VALUE));
1830 return GL_WAIT_FAILED;
1831 }
1832
1833 GLenum result = GL_WAIT_FAILED;
1834 Error error = fenceSync->clientWait(flags, timeout, &result);
1835 if (error.isError())
1836 {
1837 context->handleError(error);
1838 return GL_WAIT_FAILED;
1839 }
1840
1841 return result;
1842 }
1843
1844 return GL_FALSE;
1845 }
1846
WaitSync(GLsync sync,GLbitfield flags,GLuint64 timeout)1847 void GL_APIENTRY WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
1848 {
1849 EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)",
1850 sync, flags, timeout);
1851
1852 Context *context = GetValidGlobalContext();
1853 if (context)
1854 {
1855 if (context->getClientMajorVersion() < 3)
1856 {
1857 context->handleError(Error(GL_INVALID_OPERATION));
1858 return;
1859 }
1860
1861 if (flags != 0)
1862 {
1863 context->handleError(Error(GL_INVALID_VALUE));
1864 return;
1865 }
1866
1867 if (timeout != GL_TIMEOUT_IGNORED)
1868 {
1869 context->handleError(Error(GL_INVALID_VALUE));
1870 return;
1871 }
1872
1873 FenceSync *fenceSync = context->getFenceSync(sync);
1874
1875 if (!fenceSync)
1876 {
1877 context->handleError(Error(GL_INVALID_VALUE));
1878 return;
1879 }
1880
1881 Error error = fenceSync->serverWait(flags, timeout);
1882 if (error.isError())
1883 {
1884 context->handleError(error);
1885 }
1886 }
1887 }
1888
GetInteger64v(GLenum pname,GLint64 * params)1889 void GL_APIENTRY GetInteger64v(GLenum pname, GLint64* params)
1890 {
1891 EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
1892 pname, params);
1893
1894 Context *context = GetValidGlobalContext();
1895 if (context)
1896 {
1897 if (context->getClientMajorVersion() < 3)
1898 {
1899 context->handleError(Error(GL_INVALID_OPERATION));
1900 return;
1901 }
1902
1903 GLenum nativeType;
1904 unsigned int numParams = 0;
1905 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
1906 {
1907 return;
1908 }
1909
1910 if (nativeType == GL_INT_64_ANGLEX)
1911 {
1912 context->getInteger64v(pname, params);
1913 }
1914 else
1915 {
1916 CastStateValues(context, nativeType, pname, numParams, params);
1917 }
1918 }
1919 }
1920
GetSynciv(GLsync sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)1921 void GL_APIENTRY GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values)
1922 {
1923 EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)",
1924 sync, pname, bufSize, length, values);
1925
1926 Context *context = GetValidGlobalContext();
1927 if (context)
1928 {
1929 if (context->getClientMajorVersion() < 3)
1930 {
1931 context->handleError(Error(GL_INVALID_OPERATION));
1932 return;
1933 }
1934
1935 if (bufSize < 0)
1936 {
1937 context->handleError(Error(GL_INVALID_VALUE));
1938 return;
1939 }
1940
1941 FenceSync *fenceSync = context->getFenceSync(sync);
1942
1943 if (!fenceSync)
1944 {
1945 context->handleError(Error(GL_INVALID_VALUE));
1946 return;
1947 }
1948
1949 switch (pname)
1950 {
1951 case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break;
1952 case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break;
1953 case GL_SYNC_FLAGS: values[0] = static_cast<GLint>(fenceSync->getFlags()); break;
1954
1955 case GL_SYNC_STATUS:
1956 {
1957 Error error = fenceSync->getStatus(values);
1958 if (error.isError())
1959 {
1960 context->handleError(error);
1961 return;
1962 }
1963 break;
1964 }
1965
1966 default:
1967 context->handleError(Error(GL_INVALID_ENUM));
1968 return;
1969 }
1970 }
1971 }
1972
GetInteger64i_v(GLenum target,GLuint index,GLint64 * data)1973 void GL_APIENTRY GetInteger64i_v(GLenum target, GLuint index, GLint64* data)
1974 {
1975 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)",
1976 target, index, data);
1977
1978 Context *context = GetValidGlobalContext();
1979 if (context)
1980 {
1981 if (!context->skipValidation() && !ValidateGetInteger64i_v(context, target, index, data))
1982 {
1983 return;
1984 }
1985 context->getInteger64i_v(target, index, data);
1986 }
1987 }
1988
GetBufferParameteri64v(GLenum target,GLenum pname,GLint64 * params)1989 void GL_APIENTRY GetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params)
1990 {
1991 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)",
1992 target, pname, params);
1993
1994 Context *context = GetValidGlobalContext();
1995 if (context)
1996 {
1997 if (!context->skipValidation() &&
1998 !ValidateGetBufferParameteri64v(context, target, pname, params))
1999 {
2000 return;
2001 }
2002
2003 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2004 QueryBufferParameteri64v(buffer, pname, params);
2005 }
2006 }
2007
GenSamplers(GLsizei count,GLuint * samplers)2008 void GL_APIENTRY GenSamplers(GLsizei count, GLuint* samplers)
2009 {
2010 EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers);
2011
2012 Context *context = GetValidGlobalContext();
2013 if (context)
2014 {
2015 if (!context->skipValidation() && !ValidateGenSamplers(context, count, samplers))
2016 {
2017 return;
2018 }
2019
2020 for (int i = 0; i < count; i++)
2021 {
2022 samplers[i] = context->createSampler();
2023 }
2024 }
2025 }
2026
DeleteSamplers(GLsizei count,const GLuint * samplers)2027 void GL_APIENTRY DeleteSamplers(GLsizei count, const GLuint* samplers)
2028 {
2029 EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers);
2030
2031 Context *context = GetValidGlobalContext();
2032 if (context)
2033 {
2034 if (!context->skipValidation() && !ValidateDeleteSamplers(context, count, samplers))
2035 {
2036 return;
2037 }
2038
2039 for (int i = 0; i < count; i++)
2040 {
2041 context->deleteSampler(samplers[i]);
2042 }
2043 }
2044 }
2045
IsSampler(GLuint sampler)2046 GLboolean GL_APIENTRY IsSampler(GLuint sampler)
2047 {
2048 EVENT("(GLuint sampler = %u)", sampler);
2049
2050 Context *context = GetValidGlobalContext();
2051 if (context)
2052 {
2053 if (context->getClientMajorVersion() < 3)
2054 {
2055 context->handleError(Error(GL_INVALID_OPERATION));
2056 return GL_FALSE;
2057 }
2058
2059 return context->isSampler(sampler);
2060 }
2061
2062 return GL_FALSE;
2063 }
2064
BindSampler(GLuint unit,GLuint sampler)2065 void GL_APIENTRY BindSampler(GLuint unit, GLuint sampler)
2066 {
2067 EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler);
2068
2069 Context *context = GetValidGlobalContext();
2070 if (context)
2071 {
2072 if (context->getClientMajorVersion() < 3)
2073 {
2074 context->handleError(Error(GL_INVALID_OPERATION));
2075 return;
2076 }
2077
2078 if (sampler != 0 && !context->isSampler(sampler))
2079 {
2080 context->handleError(Error(GL_INVALID_OPERATION));
2081 return;
2082 }
2083
2084 if (unit >= context->getCaps().maxCombinedTextureImageUnits)
2085 {
2086 context->handleError(Error(GL_INVALID_VALUE));
2087 return;
2088 }
2089
2090 context->bindSampler(unit, sampler);
2091 }
2092 }
2093
SamplerParameteri(GLuint sampler,GLenum pname,GLint param)2094 void GL_APIENTRY SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
2095 {
2096 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param);
2097
2098 Context *context = GetValidGlobalContext();
2099 if (context)
2100 {
2101 if (!context->skipValidation() &&
2102 !ValidateSamplerParameteri(context, sampler, pname, param))
2103 {
2104 return;
2105 }
2106
2107 context->samplerParameteri(sampler, pname, param);
2108 }
2109 }
2110
SamplerParameteriv(GLuint sampler,GLenum pname,const GLint * param)2111 void GL_APIENTRY SamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
2112 {
2113 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLint* params = 0x%0.8p)", sampler,
2114 pname, param);
2115
2116 Context *context = GetValidGlobalContext();
2117 if (context)
2118 {
2119 if (!context->skipValidation() &&
2120 !ValidateSamplerParameteriv(context, sampler, pname, param))
2121 {
2122 return;
2123 }
2124
2125 context->samplerParameteriv(sampler, pname, param);
2126 }
2127 }
2128
SamplerParameterf(GLuint sampler,GLenum pname,GLfloat param)2129 void GL_APIENTRY SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
2130 {
2131 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param);
2132
2133 Context *context = GetValidGlobalContext();
2134 if (context)
2135 {
2136 if (!context->skipValidation() &&
2137 !ValidateSamplerParameterf(context, sampler, pname, param))
2138 {
2139 return;
2140 }
2141
2142 context->samplerParameterf(sampler, pname, param);
2143 }
2144 }
2145
SamplerParameterfv(GLuint sampler,GLenum pname,const GLfloat * param)2146 void GL_APIENTRY SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
2147 {
2148 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, const GLfloat* params = 0x%0.8p)", sampler,
2149 pname, param);
2150
2151 Context *context = GetValidGlobalContext();
2152 if (context)
2153 {
2154 if (!context->skipValidation() &&
2155 !ValidateSamplerParameterfv(context, sampler, pname, param))
2156 {
2157 return;
2158 }
2159
2160 context->samplerParameterfv(sampler, pname, param);
2161 }
2162 }
2163
GetSamplerParameteriv(GLuint sampler,GLenum pname,GLint * params)2164 void GL_APIENTRY GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
2165 {
2166 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname,
2167 params);
2168
2169 Context *context = GetValidGlobalContext();
2170 if (context)
2171 {
2172 if (!context->skipValidation() &&
2173 !ValidateGetSamplerParameteriv(context, sampler, pname, params))
2174 {
2175 return;
2176 }
2177
2178 context->getSamplerParameteriv(sampler, pname, params);
2179 }
2180 }
2181
GetSamplerParameterfv(GLuint sampler,GLenum pname,GLfloat * params)2182 void GL_APIENTRY GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
2183 {
2184 EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params);
2185
2186 Context *context = GetValidGlobalContext();
2187 if (context)
2188 {
2189 if (!context->skipValidation() &&
2190 !ValidateGetSamplerParameterfv(context, sampler, pname, params))
2191 {
2192 return;
2193 }
2194
2195 context->getSamplerParameterfv(sampler, pname, params);
2196 }
2197 }
2198
VertexAttribDivisor(GLuint index,GLuint divisor)2199 void GL_APIENTRY VertexAttribDivisor(GLuint index, GLuint divisor)
2200 {
2201 EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor);
2202
2203 Context *context = GetValidGlobalContext();
2204 if (context)
2205 {
2206 if (context->getClientMajorVersion() < 3)
2207 {
2208 context->handleError(Error(GL_INVALID_OPERATION));
2209 return;
2210 }
2211
2212 if (index >= MAX_VERTEX_ATTRIBS)
2213 {
2214 context->handleError(Error(GL_INVALID_VALUE));
2215 return;
2216 }
2217
2218 context->setVertexAttribDivisor(index, divisor);
2219 }
2220 }
2221
BindTransformFeedback(GLenum target,GLuint id)2222 void GL_APIENTRY BindTransformFeedback(GLenum target, GLuint id)
2223 {
2224 EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id);
2225
2226 Context *context = GetValidGlobalContext();
2227 if (context)
2228 {
2229 if (context->getClientMajorVersion() < 3)
2230 {
2231 context->handleError(Error(GL_INVALID_OPERATION));
2232 return;
2233 }
2234
2235 switch (target)
2236 {
2237 case GL_TRANSFORM_FEEDBACK:
2238 {
2239 // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1)
2240 TransformFeedback *curTransformFeedback =
2241 context->getGLState().getCurrentTransformFeedback();
2242 if (curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused())
2243 {
2244 context->handleError(Error(GL_INVALID_OPERATION));
2245 return;
2246 }
2247
2248 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1)
2249 if (!context->isTransformFeedbackGenerated(id))
2250 {
2251 context->handleError(
2252 Error(GL_INVALID_OPERATION,
2253 "Cannot bind a transform feedback object that does not exist."));
2254 return;
2255 }
2256
2257 context->bindTransformFeedback(id);
2258 }
2259 break;
2260
2261 default:
2262 context->handleError(Error(GL_INVALID_ENUM));
2263 return;
2264 }
2265 }
2266 }
2267
DeleteTransformFeedbacks(GLsizei n,const GLuint * ids)2268 void GL_APIENTRY DeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
2269 {
2270 EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids);
2271
2272 Context *context = GetValidGlobalContext();
2273 if (context)
2274 {
2275 if (!context->skipValidation() && !ValidateDeleteTransformFeedbacks(context, n, ids))
2276 {
2277 return;
2278 }
2279
2280 for (int i = 0; i < n; i++)
2281 {
2282 context->deleteTransformFeedback(ids[i]);
2283 }
2284 }
2285 }
2286
GenTransformFeedbacks(GLsizei n,GLuint * ids)2287 void GL_APIENTRY GenTransformFeedbacks(GLsizei n, GLuint* ids)
2288 {
2289 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids);
2290
2291 Context *context = GetValidGlobalContext();
2292 if (context)
2293 {
2294 if (!context->skipValidation() && !ValidateGenTransformFeedbacks(context, n, ids))
2295 {
2296 return;
2297 }
2298
2299 for (int i = 0; i < n; i++)
2300 {
2301 ids[i] = context->createTransformFeedback();
2302 }
2303 }
2304 }
2305
IsTransformFeedback(GLuint id)2306 GLboolean GL_APIENTRY IsTransformFeedback(GLuint id)
2307 {
2308 EVENT("(GLuint id = %u)", id);
2309
2310 Context *context = GetValidGlobalContext();
2311 if (context)
2312 {
2313 if (context->getClientMajorVersion() < 3)
2314 {
2315 context->handleError(Error(GL_INVALID_OPERATION));
2316 return GL_FALSE;
2317 }
2318
2319 if (id == 0)
2320 {
2321 // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
2322 // returns FALSE
2323 return GL_FALSE;
2324 }
2325
2326 const TransformFeedback *transformFeedback = context->getTransformFeedback(id);
2327 return ((transformFeedback != nullptr) ? GL_TRUE : GL_FALSE);
2328 }
2329
2330 return GL_FALSE;
2331 }
2332
PauseTransformFeedback(void)2333 void GL_APIENTRY PauseTransformFeedback(void)
2334 {
2335 EVENT("(void)");
2336
2337 Context *context = GetValidGlobalContext();
2338 if (context)
2339 {
2340 if (context->getClientMajorVersion() < 3)
2341 {
2342 context->handleError(Error(GL_INVALID_OPERATION));
2343 return;
2344 }
2345
2346 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2347 ASSERT(transformFeedback != NULL);
2348
2349 // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86)
2350 if (!transformFeedback->isActive() || transformFeedback->isPaused())
2351 {
2352 context->handleError(Error(GL_INVALID_OPERATION));
2353 return;
2354 }
2355
2356 transformFeedback->pause();
2357 }
2358 }
2359
ResumeTransformFeedback(void)2360 void GL_APIENTRY ResumeTransformFeedback(void)
2361 {
2362 EVENT("(void)");
2363
2364 Context *context = GetValidGlobalContext();
2365 if (context)
2366 {
2367 if (context->getClientMajorVersion() < 3)
2368 {
2369 context->handleError(Error(GL_INVALID_OPERATION));
2370 return;
2371 }
2372
2373 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2374 ASSERT(transformFeedback != NULL);
2375
2376 // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
2377 if (!transformFeedback->isActive() || !transformFeedback->isPaused())
2378 {
2379 context->handleError(Error(GL_INVALID_OPERATION));
2380 return;
2381 }
2382
2383 transformFeedback->resume();
2384 }
2385 }
2386
GetProgramBinary(GLuint program,GLsizei bufSize,GLsizei * length,GLenum * binaryFormat,GLvoid * binary)2387 void GL_APIENTRY GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary)
2388 {
2389 EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)",
2390 program, bufSize, length, binaryFormat, binary);
2391
2392 Context *context = GetValidGlobalContext();
2393 if (context)
2394 {
2395 if (!ValidateGetProgramBinary(context, program, bufSize, length, binaryFormat, binary))
2396 {
2397 return;
2398 }
2399
2400 Program *programObject = context->getProgram(program);
2401 ASSERT(programObject != nullptr);
2402
2403 Error error = programObject->saveBinary(binaryFormat, binary, bufSize, length);
2404 if (error.isError())
2405 {
2406 context->handleError(error);
2407 return;
2408 }
2409 }
2410 }
2411
ProgramBinary(GLuint program,GLenum binaryFormat,const GLvoid * binary,GLsizei length)2412 void GL_APIENTRY ProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length)
2413 {
2414 EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
2415 program, binaryFormat, binary, length);
2416
2417 Context *context = GetValidGlobalContext();
2418 if (context)
2419 {
2420 if (!ValidateProgramBinary(context, program, binaryFormat, binary, length))
2421 {
2422 return;
2423 }
2424
2425 Program *programObject = context->getProgram(program);
2426 ASSERT(programObject != nullptr);
2427
2428 Error error = programObject->loadBinary(binaryFormat, binary, length);
2429 if (error.isError())
2430 {
2431 context->handleError(error);
2432 return;
2433 }
2434 }
2435 }
2436
ProgramParameteri(GLuint program,GLenum pname,GLint value)2437 void GL_APIENTRY ProgramParameteri(GLuint program, GLenum pname, GLint value)
2438 {
2439 EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)",
2440 program, pname, value);
2441
2442 Context *context = GetValidGlobalContext();
2443 if (context)
2444 {
2445 if (!context->skipValidation() &&
2446 !ValidateProgramParameteri(context, program, pname, value))
2447 {
2448 return;
2449 }
2450
2451 context->programParameteri(program, pname, value);
2452 }
2453 }
2454
InvalidateFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments)2455 void GL_APIENTRY InvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments)
2456 {
2457 EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)",
2458 target, numAttachments, attachments);
2459
2460 Context *context = GetValidGlobalContext();
2461 if (context)
2462 {
2463 if (!context->skipValidation() &&
2464 !ValidateInvalidateFramebuffer(context, target, numAttachments, attachments))
2465 {
2466 return;
2467 }
2468
2469 context->invalidateFramebuffer(target, numAttachments, attachments);
2470 }
2471 }
2472
InvalidateSubFramebuffer(GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)2473 void GL_APIENTRY InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height)
2474 {
2475 EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, "
2476 "GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
2477 target, numAttachments, attachments, x, y, width, height);
2478
2479 Context *context = GetValidGlobalContext();
2480 if (context)
2481 {
2482 if (!context->skipValidation() &&
2483 !ValidateInvalidateFramebuffer(context, target, numAttachments, attachments))
2484 {
2485 return;
2486 }
2487
2488 context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
2489 }
2490 }
2491
TexStorage2D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)2492 void GL_APIENTRY TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
2493 {
2494 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
2495 target, levels, internalformat, width, height);
2496
2497 Context *context = GetValidGlobalContext();
2498 if (context)
2499 {
2500 if (context->getClientMajorVersion() < 3)
2501 {
2502 context->handleError(Error(GL_INVALID_OPERATION));
2503 return;
2504 }
2505
2506 if (!ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width,
2507 height, 1))
2508 {
2509 return;
2510 }
2511
2512 Extents size(width, height, 1);
2513 Texture *texture = context->getTargetTexture(target);
2514 Error error = texture->setStorage(target, levels, internalformat, size);
2515 if (error.isError())
2516 {
2517 context->handleError(error);
2518 return;
2519 }
2520 }
2521 }
2522
TexStorage3D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)2523 void GL_APIENTRY TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
2524 {
2525 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
2526 "GLsizei height = %d, GLsizei depth = %d)",
2527 target, levels, internalformat, width, height, depth);
2528
2529 Context *context = GetValidGlobalContext();
2530 if (context)
2531 {
2532 if (context->getClientMajorVersion() < 3)
2533 {
2534 context->handleError(Error(GL_INVALID_OPERATION));
2535 return;
2536 }
2537
2538 if (!ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width,
2539 height, depth))
2540 {
2541 return;
2542 }
2543
2544 Extents size(width, height, depth);
2545 Texture *texture = context->getTargetTexture(target);
2546 Error error = texture->setStorage(target, levels, internalformat, size);
2547 if (error.isError())
2548 {
2549 context->handleError(error);
2550 return;
2551 }
2552 }
2553 }
2554
GetInternalformativ(GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLint * params)2555 void GL_APIENTRY GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params)
2556 {
2557 EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, "
2558 "GLint* params = 0x%0.8p)",
2559 target, internalformat, pname, bufSize, params);
2560
2561 Context *context = GetValidGlobalContext();
2562 if (context)
2563 {
2564 if (!context->skipValidation() &&
2565 !ValidateGetInternalFormativ(context, target, internalformat, pname, bufSize, params))
2566 {
2567 return;
2568 }
2569
2570 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
2571 QueryInternalFormativ(formatCaps, pname, bufSize, params);
2572 }
2573 }
2574
2575 }
2576