1e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang//
2cec3590a151059813b91b33cd5e000c94f5bccaaGeoff Lang// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
3e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang// Use of this source code is governed by a BSD-style license that can be
4e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang// found in the LICENSE file.
5e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang//
6e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
7e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang// validationES.h: Validation functions for generic OpenGL ES entry point parameters
8e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
9e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "libGLESv2/validationES.h"
1026e9195fdcf536f07e4760656b063262bda9b60dJamie Madill#include "libGLESv2/validationES2.h"
1126e9195fdcf536f07e4760656b063262bda9b60dJamie Madill#include "libGLESv2/validationES3.h"
12e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "libGLESv2/Context.h"
13e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "libGLESv2/Texture.h"
14e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "libGLESv2/Framebuffer.h"
15e261b44af7631c31ddca8601490e7445af5a3341Jamie Madill#include "libGLESv2/FramebufferAttachment.h"
16e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "libGLESv2/formatutils.h"
17e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "libGLESv2/main.h"
18db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill#include "libGLESv2/Query.h"
193639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill#include "libGLESv2/ProgramBinary.h"
20250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill#include "libGLESv2/TransformFeedback.h"
21d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill#include "libGLESv2/VertexArray.h"
222b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill#include "libGLESv2/renderer/BufferImpl.h"
23e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
24e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "common/mathutil.h"
25e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang#include "common/utilities.h"
26e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
27e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Langnamespace gl
28e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang{
29e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
300550d0389a59a50a1df0df3484ecefc864715e26Geoff Langbool ValidCap(const Context *context, GLenum cap)
310550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang{
320550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang    switch (cap)
330550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang    {
340550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_CULL_FACE:
350550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_POLYGON_OFFSET_FILL:
360550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_SAMPLE_ALPHA_TO_COVERAGE:
370550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_SAMPLE_COVERAGE:
380550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_SCISSOR_TEST:
390550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_STENCIL_TEST:
400550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_DEPTH_TEST:
410550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_BLEND:
420550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_DITHER:
430550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang        return true;
440550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
450550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      case GL_RASTERIZER_DISCARD:
460550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang        return (context->getClientVersion() >= 3);
470550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang      default:
480550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang        return false;
490550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang    }
500550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang}
510550d0389a59a50a1df0df3484ecefc864715e26Geoff Lang
521fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madillbool ValidTextureTarget(const Context *context, GLenum target)
5335d1501b7bcbacd7af96a65a52fb545c772e41bfJamie Madill{
54d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill    switch (target)
5535d1501b7bcbacd7af96a65a52fb545c772e41bfJamie Madill    {
56d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill      case GL_TEXTURE_2D:
57d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill      case GL_TEXTURE_CUBE_MAP:
58d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill        return true;
59d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill
60d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill      case GL_TEXTURE_3D:
61d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill      case GL_TEXTURE_2D_ARRAY:
62d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill        return (context->getClientVersion() >= 3);
6335d1501b7bcbacd7af96a65a52fb545c772e41bfJamie Madill
64d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill      default:
65d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill        return false;
66d7460c7e3769793f62749c137fe7c82e7eda5cc9Jamie Madill    }
6735d1501b7bcbacd7af96a65a52fb545c772e41bfJamie Madill}
6835d1501b7bcbacd7af96a65a52fb545c772e41bfJamie Madill
694dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods// This function differs from ValidTextureTarget in that the target must be
704dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods// usable as the destination of a 2D operation-- so a cube face is valid, but
714dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods// GL_TEXTURE_CUBE_MAP is not.
72560a8d889b6866d7d29da968971818437e9cde36Jamie Madill// Note: duplicate of IsInternalTextureTarget
734dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woodsbool ValidTexture2DDestinationTarget(const Context *context, GLenum target)
744dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods{
754dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods    switch (target)
764dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods    {
774dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_2D:
784dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
794dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
804dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
814dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
824dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
834dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
844dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods        return true;
854dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_2D_ARRAY:
864dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      case GL_TEXTURE_3D:
874dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods        return (context->getClientVersion() >= 3);
884dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods      default:
894dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods        return false;
904dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods    }
914dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods}
924dfed837cbbdf55d82b2a602d9f5806201f80fa7Shannon Woods
931fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madillbool ValidFramebufferTarget(GLenum target)
941fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill{
951fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    META_ASSERT(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER && GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER);
961fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill
971fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    switch (target)
981fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    {
991fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill      case GL_FRAMEBUFFER:      return true;
1001fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill      case GL_READ_FRAMEBUFFER: return true;
1011fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill      case GL_DRAW_FRAMEBUFFER: return true;
1021fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill      default:                  return false;
1031fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    }
1041fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill}
1051fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill
1068c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madillbool ValidBufferTarget(const Context *context, GLenum target)
1078c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill{
1088c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill    switch (target)
1098c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill    {
1108c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      case GL_ARRAY_BUFFER:
1118c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      case GL_ELEMENT_ARRAY_BUFFER:
1128c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill        return true;
1138c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill
1148c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      case GL_PIXEL_PACK_BUFFER:
1158c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      case GL_PIXEL_UNPACK_BUFFER:
116c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        return context->getExtensions().pixelBufferObject;
117158c43846f00a3c283c20898ddaf2e6705b51103Shannon Woods
118b3801744ed9df17a7d8d290e203938818ad90addShannon Woods      case GL_COPY_READ_BUFFER:
119b3801744ed9df17a7d8d290e203938818ad90addShannon Woods      case GL_COPY_WRITE_BUFFER:
1208c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      case GL_TRANSFORM_FEEDBACK_BUFFER:
1218c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      case GL_UNIFORM_BUFFER:
1228c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill        return (context->getClientVersion() >= 3);
1238c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill
1248c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill      default:
1258c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill        return false;
1268c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill    }
1278c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill}
1288c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madill
12970656a64851b8014a325dd711297054032e466c1Jamie Madillbool ValidBufferParameter(const Context *context, GLenum pname)
13070656a64851b8014a325dd711297054032e466c1Jamie Madill{
13170656a64851b8014a325dd711297054032e466c1Jamie Madill    switch (pname)
13270656a64851b8014a325dd711297054032e466c1Jamie Madill    {
13370656a64851b8014a325dd711297054032e466c1Jamie Madill      case GL_BUFFER_USAGE:
13470656a64851b8014a325dd711297054032e466c1Jamie Madill      case GL_BUFFER_SIZE:
13570656a64851b8014a325dd711297054032e466c1Jamie Madill        return true;
13670656a64851b8014a325dd711297054032e466c1Jamie Madill
13770656a64851b8014a325dd711297054032e466c1Jamie Madill      // GL_BUFFER_MAP_POINTER is a special case, and may only be
13870656a64851b8014a325dd711297054032e466c1Jamie Madill      // queried with GetBufferPointerv
13970656a64851b8014a325dd711297054032e466c1Jamie Madill      case GL_BUFFER_ACCESS_FLAGS:
14070656a64851b8014a325dd711297054032e466c1Jamie Madill      case GL_BUFFER_MAPPED:
14170656a64851b8014a325dd711297054032e466c1Jamie Madill      case GL_BUFFER_MAP_OFFSET:
14270656a64851b8014a325dd711297054032e466c1Jamie Madill      case GL_BUFFER_MAP_LENGTH:
14370656a64851b8014a325dd711297054032e466c1Jamie Madill        return (context->getClientVersion() >= 3);
14470656a64851b8014a325dd711297054032e466c1Jamie Madill
14570656a64851b8014a325dd711297054032e466c1Jamie Madill      default:
14670656a64851b8014a325dd711297054032e466c1Jamie Madill        return false;
14770656a64851b8014a325dd711297054032e466c1Jamie Madill    }
14870656a64851b8014a325dd711297054032e466c1Jamie Madill}
14970656a64851b8014a325dd711297054032e466c1Jamie Madill
1508c96d58af5a5994c81b81032f775dc7d24cb5661Jamie Madillbool ValidMipLevel(const Context *context, GLenum target, GLint level)
151ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang{
152aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang    size_t maxDimension = 0;
153ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    switch (target)
154ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    {
155aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang      case GL_TEXTURE_2D:                  maxDimension = context->getCaps().max2DTextureSize;       break;
156ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      case GL_TEXTURE_CUBE_MAP:
157ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
158ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
159ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
160ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
161ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
162aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: maxDimension = context->getCaps().maxCubeMapTextureSize;  break;
163aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang      case GL_TEXTURE_3D:                  maxDimension = context->getCaps().max3DTextureSize;       break;
164aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang      case GL_TEXTURE_2D_ARRAY:            maxDimension = context->getCaps().max2DTextureSize;       break;
165ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang      default: UNREACHABLE();
166ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    }
167ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang
168aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang    return level <= gl::log2(maxDimension);
169ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang}
170ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang
171b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidImageSize(const Context *context, GLenum target, GLint level,
1724fd75c1c991e86ed1d1c1e43ef0220c5491605b1Jamie Madill                    GLsizei width, GLsizei height, GLsizei depth)
173ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang{
174ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    if (level < 0 || width < 0 || height < 0 || depth < 0)
175ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    {
176ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang        return false;
177ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    }
178ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang
179c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang    if (!context->getExtensions().textureNPOT &&
1804fd75c1c991e86ed1d1c1e43ef0220c5491605b1Jamie Madill        (level != 0 && (!gl::isPow2(width) || !gl::isPow2(height) || !gl::isPow2(depth))))
181ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    {
182ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang        return false;
183ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    }
184ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang
185ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    if (!ValidMipLevel(context, target, level))
186ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    {
187ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang        return false;
188ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    }
189ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang
190ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang    return true;
191ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang}
192ce6356958ba86c2b09e62e1250cabd6bab16a082Geoff Lang
193b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidCompressedImageSize(const Context *context, GLenum internalFormat, GLsizei width, GLsizei height)
194d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang{
1955d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat);
1965d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if (!formatInfo.compressed)
197d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang    {
198d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang        return false;
199d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang    }
200d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang
2015d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if (width  < 0 || (static_cast<GLuint>(width)  > formatInfo.compressedBlockWidth  && width  % formatInfo.compressedBlockWidth != 0) ||
2025d601382b51c29d1670b58c01360416bd929842dGeoff Lang        height < 0 || (static_cast<GLuint>(height) > formatInfo.compressedBlockHeight && height % formatInfo.compressedBlockHeight != 0))
203d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang    {
204d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang        return false;
205d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang    }
206d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang
207d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang    return true;
208d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang}
209d4f180b2a52c1a11160a9756e2dbc1586337dd19Geoff Lang
21037dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Langbool ValidQueryType(const Context *context, GLenum queryType)
21137dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang{
21237dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang    META_ASSERT(GL_ANY_SAMPLES_PASSED == GL_ANY_SAMPLES_PASSED_EXT);
21337dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang    META_ASSERT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE == GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
21437dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang
21537dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang    switch (queryType)
21637dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang    {
21737dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang      case GL_ANY_SAMPLES_PASSED:
21837dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang      case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
21937dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang        return true;
22037dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang      case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
22137dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang        return (context->getClientVersion() >= 3);
22237dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang      default:
22337dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang        return false;
22437dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang    }
22537dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang}
22637dde6929d79c9a523bd6c786d2b6c6544be8c9dGeoff Lang
227b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidProgram(Context *context, GLuint id)
22848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang{
22948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will generate the
23048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    // error INVALID_VALUE if the provided name is not the name of either a shader or program object and
23148dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    // INVALID_OPERATION if the provided name identifies an object that is not the expected type."
23248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
23348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    if (context->getProgram(id) != NULL)
23448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    {
23548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang        return true;
23648dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    }
23748dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    else if (context->getShader(id) != NULL)
23848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    {
23948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang        // ID is the wrong type
240b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
241b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
24248dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    }
24348dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    else
24448dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    {
24548dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang        // No shader/program object has this ID
246b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
247b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
24848dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang    }
24948dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang}
25048dcae7b217420a7387c84a76651989e6f5f3576Geoff Lang
251b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateAttachmentTarget(gl::Context *context, GLenum attachment)
252b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill{
253b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
254b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    {
255b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
256b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill
257aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang        if (colorAttachment >= context->getCaps().maxColorAttachments)
258b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        {
259b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
260b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
261b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        }
262b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    }
263b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    else
264b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    {
265b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        switch (attachment)
266b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        {
267b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill          case GL_DEPTH_ATTACHMENT:
268b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill          case GL_STENCIL_ATTACHMENT:
269b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill            break;
270b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill
271b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill          case GL_DEPTH_STENCIL_ATTACHMENT:
272b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill            if (context->getClientVersion() < 3)
273b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill            {
274b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_ENUM));
275b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
276b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill            }
277b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill            break;
278b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill
279b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill          default:
280b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
281b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
282b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        }
283b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    }
284b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill
285b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    return true;
286b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill}
287b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill
288b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateRenderbufferStorageParameters(gl::Context *context, GLenum target, GLsizei samples,
289e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                                           GLenum internalformat, GLsizei width, GLsizei height,
290e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                                           bool angleExtension)
291e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang{
292e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    switch (target)
293e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
294e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_RENDERBUFFER:
295e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
296e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      default:
297b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
298b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
299e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
300e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
301e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (width < 0 || height < 0 || samples < 0)
302e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
303b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
304b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
305e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
306e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
3075d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
3085d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
309e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
310b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
311b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
312e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
313e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
314e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
315e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
316e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // only sized internal formats. The ES3 spec (section 4.4.2) does, however, state that the
317e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // internal format must be sized and not an integer format if samples is greater than zero.
3185d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if (formatInfo.pixelBytes == 0)
319e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
320b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
321b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
322e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
323e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
3245d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if ((formatInfo.componentType == GL_UNSIGNED_INT || formatInfo.componentType == GL_INT) && samples > 0)
325e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
326b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
327b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
328e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
329e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
330c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang    const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
3316cf8e1b906ebfcda10f0f1cc673df6688c81e0e0Geoff Lang    if (!formatCaps.renderable)
332e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
333b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
334b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
335e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
336e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
337aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang    if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
338e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
339b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
340b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
341e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
342e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
343e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
344e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // to MAX_SAMPLES_ANGLE (Context::getMaxSupportedSamples) while the ES3.0 spec (section 4.4.2)
345e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // states that samples must be less than or equal to the maximum samples for the specified
346e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // internal format.
347e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (angleExtension)
348e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
3495f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        ASSERT(context->getExtensions().framebufferMultisample);
3505f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        if (static_cast<GLuint>(samples) > context->getExtensions().maxSamples)
351e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
352b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
353b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
354e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
3555f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang
3565f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        // Check if this specific format supports enough samples
3575f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
3585f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        {
359b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_OUT_OF_MEMORY));
360b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
3615f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        }
362e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
363e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    else
364e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
3655f4c46363bf8e7eb6852c3af42a2e57157e72113Geoff Lang        if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
366e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
367b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
368b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
369e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
370e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
371e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
37253a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    GLuint handle = context->getState().getRenderbufferId();
373e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (handle == 0)
374e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
375b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
376b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
377e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
378e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
379e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    return true;
380e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang}
381e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
3821fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madillbool ValidateFramebufferRenderbufferParameters(gl::Context *context, GLenum target, GLenum attachment,
3831fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill                                               GLenum renderbuffertarget, GLuint renderbuffer)
3841fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill{
3851da3cf639e59990084b0079ffd290676e37e6753Shannon Woods    if (!ValidFramebufferTarget(target))
3861da3cf639e59990084b0079ffd290676e37e6753Shannon Woods    {
387b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
388b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
3891da3cf639e59990084b0079ffd290676e37e6753Shannon Woods    }
3901da3cf639e59990084b0079ffd290676e37e6753Shannon Woods
39153a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
39253a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
3931fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill
3941fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
3951fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    {
396b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
397b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
3981fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    }
3991fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill
400b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill    if (!ValidateAttachmentTarget(context, attachment))
4011fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    {
402b4472275a0c686fe2ba062e796d80375c4593708Jamie Madill        return false;
4031fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    }
4041fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill
405ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    // [OpenGL ES 2.0.25] Section 4.4.3 page 112
406ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    // [OpenGL ES 3.0.2] Section 4.4.2 page 201
407ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
408ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
409ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    if (renderbuffer != 0)
410ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    {
411ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill        if (!context->getRenderbuffer(renderbuffer))
412ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill        {
413b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
414b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
415ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill        }
416ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill    }
417ab9d82cd54156991f9f88851d3ba0c8c1f96838aJamie Madill
4181fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill    return true;
4191fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill}
4201fc7e2c5961207aa2bd1a99978d661b4cbcbf144Jamie Madill
4213c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madillstatic bool IsPartialBlit(gl::Context *context, gl::FramebufferAttachment *readBuffer, gl::FramebufferAttachment *writeBuffer,
422125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                          GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
423125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                          GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1)
424125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang{
425125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 ||
426125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        dstX1 != writeBuffer->getWidth() || dstY1 != writeBuffer->getHeight() ||
427125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        srcX1 != readBuffer->getWidth() || srcY1 != readBuffer->getHeight())
428125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
429125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        return true;
430125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
43153a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    else if (context->getState().isScissorTestEnabled())
432125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
43353a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods        const Rectangle &scissor = context->getState().getScissor();
434125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
43553a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods        return scissor.x > 0 || scissor.y > 0 ||
43653a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods               scissor.width < writeBuffer->getWidth() ||
43753a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods               scissor.height < writeBuffer->getHeight();
438125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
439125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    else
440125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    {
441125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang        return false;
442125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang    }
443125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang}
444125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang
44534dbb6f5ed0ca2cc55a3f1faaa7d6ce2f95d0c18Geoff Langbool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
446e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
447e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                                       GLenum filter, bool fromAngleExtension)
448e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang{
449e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    switch (filter)
450e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
451e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_NEAREST:
452e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
453e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_LINEAR:
454e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (fromAngleExtension)
455e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
456b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
457b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
458e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
459e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
460e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      default:
461b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
462b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
463e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
464e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
465e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
466e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
467b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
468b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
469e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
470e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
471e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (mask == 0)
472e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
473e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no
474e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        // buffers are copied.
475e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return false;
476e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
477e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
478e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (fromAngleExtension && (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0))
479e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
480e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.");
481b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
482b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
483e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
484e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
485e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
486e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    // color buffer, leaving only nearest being unfiltered from above
487e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
488e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
489b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
490b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
491e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
492e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
49353a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    if (context->getState().getReadFramebuffer()->id() == context->getState().getDrawFramebuffer()->id())
494e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
495e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (fromAngleExtension)
496e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
497e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            ERR("Blits with the same source and destination framebuffer are not supported by this "
498e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                "implementation.");
499e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
500b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
501b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
502e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
503e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
50453a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    gl::Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
50553a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    gl::Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
506e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
507e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
508e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
509b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
510b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
511e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
512e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
513e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (drawFramebuffer->getSamples() != 0)
514e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
515b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
516b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
517e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
518e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
519e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
520e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
521e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (mask & GL_COLOR_BUFFER_BIT)
522e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
5233c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
5243c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
525e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
526e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (readColorBuffer && drawColorBuffer)
527e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
528005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang            GLenum readInternalFormat = readColorBuffer->getActualFormat();
5295d601382b51c29d1670b58c01360416bd929842dGeoff Lang            const InternalFormat &readFormatInfo = GetInternalFormatInfo(readInternalFormat);
530e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
531e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
532e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
533e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                if (drawFramebuffer->isEnabledColorAttachment(i))
534e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
535005df41f8900641ed1df60700c8e2eca659a33cbGeoff Lang                    GLenum drawInternalFormat = drawFramebuffer->getColorbuffer(i)->getActualFormat();
5365d601382b51c29d1670b58c01360416bd929842dGeoff Lang                    const InternalFormat &drawFormatInfo = GetInternalFormatInfo(drawInternalFormat);
537b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang
538b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang                    // The GL ES 3.0.2 spec (pg 193) states that:
539b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang                    // 1) If the read buffer is fixed point format, the draw buffer must be as well
540b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang                    // 2) If the read buffer is an unsigned integer format, the draw buffer must be as well
541b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang                    // 3) If the read buffer is a signed integer format, the draw buffer must be as well
5425d601382b51c29d1670b58c01360416bd929842dGeoff Lang                    if ( (readFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || readFormatInfo.componentType == GL_SIGNED_NORMALIZED) &&
5435d601382b51c29d1670b58c01360416bd929842dGeoff Lang                        !(drawFormatInfo.componentType == GL_UNSIGNED_NORMALIZED || drawFormatInfo.componentType == GL_SIGNED_NORMALIZED))
544e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    {
545b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        context->recordError(Error(GL_INVALID_OPERATION));
546b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        return false;
547e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    }
548e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
5495d601382b51c29d1670b58c01360416bd929842dGeoff Lang                    if (readFormatInfo.componentType == GL_UNSIGNED_INT && drawFormatInfo.componentType != GL_UNSIGNED_INT)
550e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    {
551b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        context->recordError(Error(GL_INVALID_OPERATION));
552b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        return false;
553e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    }
554e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
5555d601382b51c29d1670b58c01360416bd929842dGeoff Lang                    if (readFormatInfo.componentType == GL_INT && drawFormatInfo.componentType != GL_INT)
556e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    {
557b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        context->recordError(Error(GL_INVALID_OPERATION));
558b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        return false;
559e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    }
560e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
561b2f3d05cbed0cc635a64a4bff77767d656d41eadGeoff Lang                    if (readColorBuffer->getSamples() > 0 && (readInternalFormat != drawInternalFormat || !sameBounds))
562e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    {
563b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        context->recordError(Error(GL_INVALID_OPERATION));
564b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                        return false;
565e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    }
566e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
567e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
568e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
5695d601382b51c29d1670b58c01360416bd929842dGeoff Lang            if ((readFormatInfo.componentType == GL_INT || readFormatInfo.componentType == GL_UNSIGNED_INT) && filter == GL_LINEAR)
570e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
571b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
572b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
573e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
574e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
575e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (fromAngleExtension)
576e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
577e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
578e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                if (readColorbufferType != GL_TEXTURE_2D && readColorbufferType != GL_RENDERBUFFER)
579e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
580b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
581b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
582e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
583e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
584e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
585e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
586e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
587e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    {
588e92a3546da271f33110714508529fef7306c4656Jamie Madill                        FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(colorAttachment);
589e92a3546da271f33110714508529fef7306c4656Jamie Madill                        ASSERT(attachment);
590e92a3546da271f33110714508529fef7306c4656Jamie Madill
591e92a3546da271f33110714508529fef7306c4656Jamie Madill                        if (attachment->type() != GL_TEXTURE_2D && attachment->type() != GL_RENDERBUFFER)
592e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                        {
593b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                            context->recordError(Error(GL_INVALID_OPERATION));
594b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                            return false;
595e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                        }
596e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
597e92a3546da271f33110714508529fef7306c4656Jamie Madill                        if (attachment->getActualFormat() != readColorBuffer->getActualFormat())
598e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                        {
599b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                            context->recordError(Error(GL_INVALID_OPERATION));
600b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                            return false;
601e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                        }
602e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    }
603e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
604125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                if (readFramebuffer->getSamples() != 0 && IsPartialBlit(context, readColorBuffer, drawColorBuffer,
605125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                                                        srcX0, srcY0, srcX1, srcY1,
606125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                                                        dstX0, dstY0, dstX1, dstY1))
607e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
608b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
609b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
610e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
611e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
612e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
613e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
614e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
615e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (mask & GL_DEPTH_BUFFER_BIT)
616e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
6173c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *readDepthBuffer = readFramebuffer->getDepthbuffer();
6183c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *drawDepthBuffer = drawFramebuffer->getDepthbuffer();
619e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
620e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (readDepthBuffer && drawDepthBuffer)
621e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
622e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (readDepthBuffer->getActualFormat() != drawDepthBuffer->getActualFormat())
623e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
624b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
625b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
626e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
627e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
628e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (readDepthBuffer->getSamples() > 0 && !sameBounds)
629e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
630b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
631b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
632e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
633e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
634e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (fromAngleExtension)
635e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
636125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                if (IsPartialBlit(context, readDepthBuffer, drawDepthBuffer,
637125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                  srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
638e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
639e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
640b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
641b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
642e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
643e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
644e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                if (readDepthBuffer->getSamples() != 0 || drawDepthBuffer->getSamples() != 0)
645e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
646b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
647b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
648e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
649e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
650e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
651e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
652e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
653e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    if (mask & GL_STENCIL_BUFFER_BIT)
654e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
6553c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *readStencilBuffer = readFramebuffer->getStencilbuffer();
6563c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill        gl::FramebufferAttachment *drawStencilBuffer = drawFramebuffer->getStencilbuffer();
657e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
658e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (readStencilBuffer && drawStencilBuffer)
659e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
660e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (readStencilBuffer->getActualFormat() != drawStencilBuffer->getActualFormat())
661e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
662b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
663b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
664e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
665e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
666e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (readStencilBuffer->getSamples() > 0 && !sameBounds)
667e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
668b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
669b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
670e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
671e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
672e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            if (fromAngleExtension)
673e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            {
674125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                if (IsPartialBlit(context, readStencilBuffer, drawStencilBuffer,
675125deab6241c659dab0c9bb9f55c08daecc2f534Geoff Lang                                  srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
676e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
677e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                    ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
678b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION)); // only whole-buffer copies are permitted
679b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
680e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
681e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
682e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                if (readStencilBuffer->getSamples() != 0 || drawStencilBuffer->getSamples() != 0)
683e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                {
684b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
685b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
686e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang                }
687e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            }
688e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
689e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
690e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
691e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    return true;
692e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang}
693e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
694b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateGetVertexAttribParameters(Context *context, GLenum pname)
695e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang{
696e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    switch (pname)
697e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
698e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
699e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_SIZE:
700e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
701e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_TYPE:
702e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
703e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
704e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_CURRENT_VERTEX_ATTRIB:
705e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return true;
706e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
707e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
708e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        // Don't verify ES3 context because GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE uses
709e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        // the same constant.
710e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        META_ASSERT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE);
711e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return true;
712e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
713e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
714b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        if (context->getClientVersion() < 3)
715b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        {
716b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
717b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
718b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        }
719b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return true;
720e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
721e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      default:
722b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
723b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
724e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
725e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang}
726e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
72734dbb6f5ed0ca2cc55a3f1faaa7d6ce2f95d0c18Geoff Langbool ValidateTexParamParameters(gl::Context *context, GLenum pname, GLint param)
728e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang{
729e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    switch (pname)
730e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
731e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_R:
732e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_R:
733e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_G:
734e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_B:
735e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_A:
736e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_BASE_LEVEL:
737e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAX_LEVEL:
738e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_COMPARE_MODE:
739e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_COMPARE_FUNC:
740e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MIN_LOD:
741e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAX_LOD:
742e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (context->getClientVersion() < 3)
743e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
744b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
745b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
746e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
747e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
748e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
749e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      default: break;
750e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
751e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
752e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    switch (pname)
753e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
754e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_S:
755e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_T:
756e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_R:
757e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        switch (param)
758e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
759e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_REPEAT:
760e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_CLAMP_TO_EDGE:
761e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_MIRRORED_REPEAT:
762e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            return true;
763e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          default:
764b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
765b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
766e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
767e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
768e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MIN_FILTER:
769e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        switch (param)
770e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
771e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NEAREST:
772e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_LINEAR:
773e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NEAREST_MIPMAP_NEAREST:
774e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_LINEAR_MIPMAP_NEAREST:
775e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NEAREST_MIPMAP_LINEAR:
776e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_LINEAR_MIPMAP_LINEAR:
777e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            return true;
778e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          default:
779b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
780b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
781e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
782e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
783e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
784e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAG_FILTER:
785e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        switch (param)
786e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
787e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NEAREST:
788e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_LINEAR:
789e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            return true;
790e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          default:
791b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
792b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
793e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
794e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
795e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
796e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_USAGE_ANGLE:
797e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        switch (param)
798e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
799e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NONE:
800e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
801e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            return true;
802e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          default:
803b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
804b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
805e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
806e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
807e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
808e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
809c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        if (!context->getExtensions().textureFilterAnisotropic)
810e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
811b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
812b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
813e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
814e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
815e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        // we assume the parameter passed to this validation method is truncated, not rounded
816e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        if (param < 1)
817e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
818b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
819b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
820e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
821e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return true;
822e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
823e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MIN_LOD:
824e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAX_LOD:
825e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        // any value is permissible
826e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return true;
827e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
828e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_COMPARE_MODE:
82963b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang        // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
830e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        switch (param)
831e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
832e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NONE:
833e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_COMPARE_REF_TO_TEXTURE:
834e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            return true;
835e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          default:
836b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
837b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
838e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
839e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
840e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
841e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_COMPARE_FUNC:
84263b5f1fd695007afca2329967f9db507c9d7f139Geoff Lang        // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
843e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        switch (param)
844e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        {
845e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_LEQUAL:
846e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_GEQUAL:
847e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_LESS:
848e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_GREATER:
849e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_EQUAL:
850e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NOTEQUAL:
851e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_ALWAYS:
852e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          case GL_NEVER:
853e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang            return true;
854e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang          default:
855b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
856b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
857e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        }
858e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        break;
859e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
860e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_R:
861e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_G:
862e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_B:
863e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_SWIZZLE_A:
864bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang        switch (param)
865bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang        {
866bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          case GL_RED:
867bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          case GL_GREEN:
868bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          case GL_BLUE:
869bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          case GL_ALPHA:
870bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          case GL_ZERO:
871bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          case GL_ONE:
872bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang            return true;
873bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang          default:
874b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
875b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
876bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang        }
877bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang        break;
878bc90a4804f58d2b24babe6f247db57b9a6cdc58fGeoff Lang
879e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_BASE_LEVEL:
880e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAX_LEVEL:
8818de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens        if (param < 0)
8828de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens        {
883b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
884b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
8858de682870a82cad54f3fffe5c6723e858656f7e2Nicolas Capens        }
886e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return true;
887e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
888e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      default:
889b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
890b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
891e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
892e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang}
893e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
894b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateSamplerObjectParameter(gl::Context *context, GLenum pname)
895e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang{
896e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    switch (pname)
897e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    {
898e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MIN_FILTER:
899e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAG_FILTER:
900e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_S:
901e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_T:
902e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_WRAP_R:
903e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MIN_LOD:
904e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_MAX_LOD:
905e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_COMPARE_MODE:
906e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      case GL_TEXTURE_COMPARE_FUNC:
907e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang        return true;
908e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
909e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang      default:
910b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
911b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
912e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang    }
913e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang}
914e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang
91526e9195fdcf536f07e4760656b063262bda9b60dJamie Madillbool ValidateReadPixelsParameters(gl::Context *context, GLint x, GLint y, GLsizei width, GLsizei height,
91626e9195fdcf536f07e4760656b063262bda9b60dJamie Madill                                  GLenum format, GLenum type, GLsizei *bufSize, GLvoid *pixels)
91726e9195fdcf536f07e4760656b063262bda9b60dJamie Madill{
91853a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
919893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    ASSERT(framebuffer);
92026e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
92126e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
92226e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    {
923b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
924b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
92526e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    }
92626e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
92753a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
92826e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    {
929b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
930b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
93126e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    }
93226e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
933893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    if (!framebuffer->getReadColorbuffer())
934893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    {
935b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
936b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
937893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    }
938893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
93926e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    GLenum currentInternalFormat, currentFormat, currentType;
940e4a492be45f39dffaea53c3523064844ee56e41bGeoff Lang    GLuint clientVersion = context->getClientVersion();
94126e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
942893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    context->getCurrentReadFormatType(&currentInternalFormat, &currentFormat, &currentType);
94326e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
944bdc9b2f0ed9e365bf5a4d19799d93a512f07dd32Geoff Lang    bool validReadFormat = (clientVersion < 3) ? ValidES2ReadFormatType(context, format, type) :
945bdc9b2f0ed9e365bf5a4d19799d93a512f07dd32Geoff Lang                                                 ValidES3ReadFormatType(context, currentInternalFormat, format, type);
94626e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
94726e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    if (!(currentFormat == format && currentType == type) && !validReadFormat)
94826e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    {
949b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
950b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
95126e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    }
95226e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
9535d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
9545d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const InternalFormat &sizedFormatInfo = GetInternalFormatInfo(sizedInternalFormat);
95526e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
9565d601382b51c29d1670b58c01360416bd929842dGeoff Lang    GLsizei outputPitch = sizedFormatInfo.computeRowPitch(type, width, context->getState().getPackAlignment());
95726e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    // sized query sanity check
95826e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    if (bufSize)
95926e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    {
96026e9195fdcf536f07e4760656b063262bda9b60dJamie Madill        int requiredSize = outputPitch * height;
96126e9195fdcf536f07e4760656b063262bda9b60dJamie Madill        if (requiredSize > *bufSize)
96226e9195fdcf536f07e4760656b063262bda9b60dJamie Madill        {
963b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
964b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
96526e9195fdcf536f07e4760656b063262bda9b60dJamie Madill        }
96626e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    }
96726e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
96826e9195fdcf536f07e4760656b063262bda9b60dJamie Madill    return true;
96926e9195fdcf536f07e4760656b063262bda9b60dJamie Madill}
97026e9195fdcf536f07e4760656b063262bda9b60dJamie Madill
971db2f14c0b1133507215dd3b7a30155b70885973aJamie Madillbool ValidateBeginQuery(gl::Context *context, GLenum target, GLuint id)
972db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill{
973db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    if (!ValidQueryType(context, target))
974db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    {
975b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
976b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
977db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    }
978db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
979db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    if (id == 0)
980db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    {
981b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
982b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
983db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    }
984db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
985db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
986db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // of zero, if the active query object name for <target> is non-zero (for the
987db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
988db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // the active query for either target is non-zero), if <id> is the name of an
989db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // existing query object whose type does not match <target>, or if <id> is the
990db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // active query object name for any query type, the error INVALID_OPERATION is
991db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // generated.
992db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
993db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // Ensure no other queries are active
994db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // NOTE: If other queries than occlusion are supported, we will need to check
995db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // separately that:
996db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    //    a) The query ID passed is not the current active query for any target/type
997db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    //    b) There are no active queries for the requested target (and in the case
998db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
999db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    //       no query may be active for either if glBeginQuery targets either.
100053a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    if (context->getState().isQueryActive())
1001db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    {
1002b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1003b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1004db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    }
1005db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
1006db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    Query *queryObject = context->getQuery(id, true, target);
1007db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
1008db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // check that name was obtained with glGenQueries
1009db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    if (!queryObject)
1010db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    {
1011b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1012b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1013db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    }
1014db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
1015db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    // check for type mismatch
1016db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    if (queryObject->getType() != target)
1017db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    {
1018b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1019b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1020db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    }
1021db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
1022db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill    return true;
1023db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill}
1024db2f14c0b1133507215dd3b7a30155b70885973aJamie Madill
102545c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madillbool ValidateEndQuery(gl::Context *context, GLenum target)
102645c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill{
102745c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    if (!ValidQueryType(context, target))
102845c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    {
1029b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1030b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
103145c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    }
103245c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill
103353a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    const Query *queryObject = context->getState().getActiveQuery(target);
103445c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill
103545c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    if (queryObject == NULL)
103645c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    {
1037b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1038b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
103945c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    }
104045c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill
104145c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill    return true;
104245c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill}
104345c785d35c270ca1d1168b6ca5517cb3a5a285ccJamie Madill
10443639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madillstatic bool ValidateUniformCommonBase(gl::Context *context, GLenum targetUniformType,
10453639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill                                      GLint location, GLsizei count, LinkedUniform **uniformOut)
1046d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill{
1047d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    if (count < 0)
1048d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    {
1049b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1050b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1051d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    }
1052d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill
105353a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    gl::ProgramBinary *programBinary = context->getState().getCurrentProgramBinary();
1054aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    if (!programBinary)
1055d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    {
1056b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1057b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1058d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    }
1059d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill
1060aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    if (location == -1)
1061d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    {
1062aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill        // Silently ignore the uniform command
1063aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill        return false;
1064d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    }
1065d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill
10663639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (!programBinary->isValidUniformLocation(location))
10673639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    {
1068b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1069b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
10703639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
10713639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
10723639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    LinkedUniform *uniform = programBinary->getUniformByLocation(location);
10733639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
10743639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    // attempting to write an array to a non-array uniform is an INVALID_OPERATION
10753639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (uniform->elementCount() == 1 && count > 1)
10763639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    {
1077b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1078b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
10793639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
10803639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
10813639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    *uniformOut = uniform;
1082aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    return true;
1083aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill}
1084aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill
1085aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madillbool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count)
1086aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill{
1087aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    // Check for ES3 uniform entry points
1088f257598999faf907a50d8a9f9eff28dad0ff2628Jamie Madill    if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && context->getClientVersion() < 3)
1089d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    {
1090b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1091b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1092d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    }
1093d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill
10943639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    LinkedUniform *uniform = NULL;
10953639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (!ValidateUniformCommonBase(context, uniformType, location, count, &uniform))
10963639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    {
10973639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill        return false;
10983639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
10993639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
1100f257598999faf907a50d8a9f9eff28dad0ff2628Jamie Madill    GLenum targetBoolType = VariableBoolVectorType(uniformType);
11013639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    bool samplerUniformCheck = (IsSampler(uniform->type) && uniformType == GL_INT);
11023639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
11033639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    {
1104b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1105b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
11063639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
11073639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
11083639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    return true;
1109aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill}
1110aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill
1111aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madillbool ValidateUniformMatrix(gl::Context *context, GLenum matrixType, GLint location, GLsizei count,
1112aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill                           GLboolean transpose)
1113aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill{
1114aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    // Check for ES3 uniform entry points
1115aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    int rows = VariableRowCount(matrixType);
1116aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    int cols = VariableColumnCount(matrixType);
1117aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    if (rows != cols && context->getClientVersion() < 3)
1118d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    {
1119b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1120b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1121d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill    }
1122d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill
1123aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    if (transpose != GL_FALSE && context->getClientVersion() < 3)
1124aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    {
1125b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1126b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1127aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill    }
1128aa981bd714bc3c091d74e8a2893edfca6c5b7bb4Jamie Madill
11293639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    LinkedUniform *uniform = NULL;
11303639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (!ValidateUniformCommonBase(context, matrixType, location, count, &uniform))
11313639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    {
11323639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill        return false;
11333639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
11343639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
11353639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    if (uniform->type != matrixType)
11363639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    {
1137b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1138b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
11393639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    }
11403639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill
11413639892dee8ec8cecf4bae4b0585a7cefde98d80Jamie Madill    return true;
1142d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill}
1143d7c7bb276e532e2e55963cdb07b8091d01fb018dJamie Madill
1144893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madillbool ValidateStateQuery(gl::Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
1145893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill{
1146893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    if (!context->getQueryParameterInfo(pname, nativeType, numParams))
1147893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    {
1148b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1149b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1150893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    }
1151893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1152893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
1153893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    {
1154893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
1155893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1156aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang        if (colorAttachment >= context->getCaps().maxDrawBuffers)
1157893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        {
1158b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
1159b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1160893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        }
1161893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    }
1162893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1163893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    switch (pname)
1164893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    {
1165893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      case GL_TEXTURE_BINDING_2D:
1166893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      case GL_TEXTURE_BINDING_CUBE_MAP:
1167893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      case GL_TEXTURE_BINDING_3D:
1168893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      case GL_TEXTURE_BINDING_2D_ARRAY:
11693a61c321e7ea779f23a4da72db977286897b1168Geoff Lang        if (context->getState().getActiveSampler() >= context->getCaps().maxCombinedTextureImageUnits)
1170893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        {
1171b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
1172b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1173893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        }
1174893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        break;
1175893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1176893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1177893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1178893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        {
117953a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods            Framebuffer *framebuffer = context->getState().getReadFramebuffer();
1180893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill            ASSERT(framebuffer);
1181893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill            if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1182893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill            {
1183b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
1184b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
1185893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill            }
1186893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
11873c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill            FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
11883c7fa226aeb81469b93142b54e339f13a46ab835Jamie Madill            if (!attachment)
1189893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill            {
1190b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION));
1191b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
1192893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill            }
1193893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        }
1194893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        break;
1195893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1196893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill      default:
1197893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        break;
1198893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    }
1199893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1200893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    // pname is valid, but there are no parameters to return
1201893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    if (numParams == 0)
1202893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    {
1203893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill        return false;
1204893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    }
1205893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1206893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill    return true;
1207893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill}
1208893ab0878d3358c45ced6a6fb048ea048e1faa97Jamie Madill
1209560a8d889b6866d7d29da968971818437e9cde36Jamie Madillbool ValidateCopyTexImageParametersBase(gl::Context* context, GLenum target, GLint level, GLenum internalformat, bool isSubImage,
1210560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                                        GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height,
1211560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                                        GLint border, GLenum *textureFormatOut)
1212560a8d889b6866d7d29da968971818437e9cde36Jamie Madill{
1213560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1214560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (!ValidTexture2DDestinationTarget(context, target))
1215560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1216b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1217b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1218560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1219560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1220560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (level < 0 || xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0)
1221560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1222b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1223b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1224560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1225560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1226560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1227560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1228b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1229b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1230560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1231560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1232560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (border != 0)
1233560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1234b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1235b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1236560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1237560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1238560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (!ValidMipLevel(context, target, level))
1239560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1240b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1241b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1242560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1243560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
124453a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
1245560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1246560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1247b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
1248b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1249560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1250560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
125153a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    if (context->getState().getReadFramebuffer()->id() != 0 && framebuffer->getSamples() != 0)
1252560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1253b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1254b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1255560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1256560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1257aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang    const gl::Caps &caps = context->getCaps();
1258aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang
1259560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    gl::Texture *texture = NULL;
1260560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    GLenum textureInternalFormat = GL_NONE;
1261560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    GLint textureLevelWidth = 0;
1262560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    GLint textureLevelHeight = 0;
1263560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    GLint textureLevelDepth = 0;
1264aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang    GLuint maxDimension = 0;
1265560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1266560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    switch (target)
1267560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1268560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_2D:
1269560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        {
1270560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            gl::Texture2D *texture2d = context->getTexture2D();
1271560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            if (texture2d)
1272560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            {
1273560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureInternalFormat = texture2d->getInternalFormat(level);
1274560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelWidth = texture2d->getWidth(level);
1275560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelHeight = texture2d->getHeight(level);
1276560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelDepth = 1;
1277560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                texture = texture2d;
1278aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang                maxDimension = caps.max2DTextureSize;
1279560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            }
1280560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        }
1281560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        break;
1282560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1283560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1284560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1285560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1286560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1287560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1288560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1289560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        {
1290560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            gl::TextureCubeMap *textureCube = context->getTextureCubeMap();
1291560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            if (textureCube)
1292560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            {
1293560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureInternalFormat = textureCube->getInternalFormat(target, level);
1294560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelWidth = textureCube->getWidth(target, level);
1295560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelHeight = textureCube->getHeight(target, level);
1296560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelDepth = 1;
1297560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                texture = textureCube;
1298aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang                maxDimension = caps.maxCubeMapTextureSize;
1299560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            }
1300560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        }
1301560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        break;
1302560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1303560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_2D_ARRAY:
1304560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        {
1305560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            gl::Texture2DArray *texture2dArray = context->getTexture2DArray();
1306560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            if (texture2dArray)
1307560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            {
1308560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureInternalFormat = texture2dArray->getInternalFormat(level);
1309560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelWidth = texture2dArray->getWidth(level);
1310560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelHeight = texture2dArray->getHeight(level);
1311560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelDepth = texture2dArray->getLayers(level);
1312560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                texture = texture2dArray;
1313aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang                maxDimension = caps.max2DTextureSize;
1314560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            }
1315560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        }
1316560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        break;
1317560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1318560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      case GL_TEXTURE_3D:
1319560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        {
1320560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            gl::Texture3D *texture3d = context->getTexture3D();
1321560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            if (texture3d)
1322560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            {
1323560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureInternalFormat = texture3d->getInternalFormat(level);
1324560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelWidth = texture3d->getWidth(level);
1325560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelHeight = texture3d->getHeight(level);
1326560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                textureLevelDepth = texture3d->getDepth(level);
1327560a8d889b6866d7d29da968971818437e9cde36Jamie Madill                texture = texture3d;
1328aae65a4e53fae703cc0ea92adc649247367917fdGeoff Lang                maxDimension = caps.max3DTextureSize;
1329560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            }
1330560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        }
1331560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        break;
1332560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1333560a8d889b6866d7d29da968971818437e9cde36Jamie Madill      default:
1334b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1335b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1336560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1337560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1338560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (!texture)
1339560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1340b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1341b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1342560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1343560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1344560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (texture->isImmutable() && !isSubImage)
1345560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1346b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1347b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1348560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1349560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
13505d601382b51c29d1670b58c01360416bd929842dGeoff Lang    const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat);
13515d601382b51c29d1670b58c01360416bd929842dGeoff Lang
13525d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if (formatInfo.depthBits > 0)
1353560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1354b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1355b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1356560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1357560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
13585d601382b51c29d1670b58c01360416bd929842dGeoff Lang    if (formatInfo.compressed)
1359560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
13605d601382b51c29d1670b58c01360416bd929842dGeoff Lang        if (((width % formatInfo.compressedBlockWidth) != 0 && width != textureLevelWidth) ||
13615d601382b51c29d1670b58c01360416bd929842dGeoff Lang            ((height % formatInfo.compressedBlockHeight) != 0 && height != textureLevelHeight))
1362560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        {
1363b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
1364b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1365560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        }
1366560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
1367560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1368560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    if (isSubImage)
1369560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    {
1370560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        if (xoffset + width > textureLevelWidth ||
1371560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            yoffset + height > textureLevelHeight ||
1372560a8d889b6866d7d29da968971818437e9cde36Jamie Madill            zoffset >= textureLevelDepth)
1373560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        {
1374b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
1375b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1376560a8d889b6866d7d29da968971818437e9cde36Jamie Madill        }
1377560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    }
13786f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill    else
13796f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill    {
13806f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        if (IsCubemapTextureTarget(target) && width != height)
13816f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        {
1382b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
1383b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
13846f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        }
13856f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill
13865d601382b51c29d1670b58c01360416bd929842dGeoff Lang        if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
13876f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        {
1388b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
1389b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
13906f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        }
13916f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill
13926f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        int maxLevelDimension = (maxDimension >> level);
13936f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        if (static_cast<int>(width) > maxLevelDimension || static_cast<int>(height) > maxLevelDimension)
13946f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        {
1395b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
1396b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
13976f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill        }
13986f38f823362c24062bed35ff7fbf5c35dc7d7f84Jamie Madill    }
1399560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1400560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    *textureFormatOut = textureInternalFormat;
1401560a8d889b6866d7d29da968971818437e9cde36Jamie Madill    return true;
1402560a8d889b6866d7d29da968971818437e9cde36Jamie Madill}
1403560a8d889b6866d7d29da968971818437e9cde36Jamie Madill
1404b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langstatic bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsizei maxVertex, GLsizei primcount)
1405250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill{
14061aeb13146c83054917705635ac381500da22b85cJamie Madill    switch (mode)
14071aeb13146c83054917705635ac381500da22b85cJamie Madill    {
14081aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_POINTS:
14091aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_LINES:
14101aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_LINE_LOOP:
14111aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_LINE_STRIP:
14121aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_TRIANGLES:
14131aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_TRIANGLE_STRIP:
14141aeb13146c83054917705635ac381500da22b85cJamie Madill      case GL_TRIANGLE_FAN:
14151aeb13146c83054917705635ac381500da22b85cJamie Madill        break;
14161aeb13146c83054917705635ac381500da22b85cJamie Madill      default:
1417b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1418b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
14191aeb13146c83054917705635ac381500da22b85cJamie Madill    }
14201aeb13146c83054917705635ac381500da22b85cJamie Madill
1421fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    if (count < 0)
1422250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1423b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1424b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1425250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1426250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1427b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang    const State &state = context->getState();
1428b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang
1429250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    // Check for mapped buffers
1430d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    if (state.hasMappedBuffer(GL_ARRAY_BUFFER))
1431250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1432b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1433b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1434250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1435250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1436d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
1437ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill    if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
1438d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill        state.getStencilRef() != state.getStencilBackRef() ||
1439ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill        depthStencilState.stencilMask != depthStencilState.stencilBackMask)
1440ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill    {
1441ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill        // Note: these separate values are not supported in WebGL, due to D3D's limitations.
1442ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill        // See Section 6.10 of the WebGL 1.0 spec
1443ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill        ERR("This ANGLE implementation does not support separate front/back stencil "
1444ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill            "writemasks, reference values, or stencil mask values.");
1445b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1446b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1447ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill    }
1448ac528015b35c121df09be7d3e048cd94564f99d4Jamie Madill
1449d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    const gl::Framebuffer *fbo = state.getDrawFramebuffer();
145013f7d7dc0b09fd7e508172c7d804ce65219b2bb5Jamie Madill    if (!fbo || fbo->completeness() != GL_FRAMEBUFFER_COMPLETE)
145113f7d7dc0b09fd7e508172c7d804ce65219b2bb5Jamie Madill    {
1452b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_FRAMEBUFFER_OPERATION));
1453b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
145413f7d7dc0b09fd7e508172c7d804ce65219b2bb5Jamie Madill    }
14559efa581d0e8f251b88f5a2f432ddb20655036c77Jamie Madill
1456d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    if (state.getCurrentProgramId() == 0)
1457d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill    {
1458b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1459b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1460d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill    }
1461d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill
1462d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
146343a53e2434f4fe042bee061fc369a93314b710deBrandon Jones    if (!programBinary->validateSamplers(NULL, context->getCaps()))
1464d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill    {
1465b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1466b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1467d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill    }
1468d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill
14692b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    // Buffer validations
14702b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    const VertexArray *vao = state.getVertexArray();
14712b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
14722b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    {
14732b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
14742b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        bool attribActive = (programBinary->getSemanticIndex(attributeIndex) != -1);
14752b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        if (attribActive && attrib.enabled)
14762b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        {
14772b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            gl::Buffer *buffer = attrib.buffer.get();
14782b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
14792b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            if (buffer)
14802b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            {
14812b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                GLint64 attribStride = static_cast<GLint64>(ComputeVertexAttributeStride(attrib));
14822b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                GLint64 maxVertexElement = 0;
14832b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
14842b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                if (attrib.divisor > 0)
14852b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                {
14862b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                    maxVertexElement = static_cast<GLint64>(primcount) / static_cast<GLint64>(attrib.divisor);
14872b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                }
14882b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                else
14892b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                {
14902b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                    maxVertexElement = static_cast<GLint64>(maxVertex);
14912b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                }
14922b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
14932b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                GLint64 attribDataSize = maxVertexElement * attribStride;
14942b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
14952b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                // [OpenGL ES 3.0.2] section 2.9.4 page 40:
14962b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                // We can return INVALID_OPERATION if our vertex attribute does not have
14972b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                // enough backing data.
14982b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                if (attribDataSize > buffer->getSize())
14992b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                {
1500b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
1501b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
15022b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                }
15032b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            }
15042b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            else if (attrib.pointer == NULL)
15052b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            {
15062b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                // This is an application error that would normally result in a crash,
15072b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                // but we catch it and return an error
1508b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                context->recordError(Error(GL_INVALID_OPERATION, "An enabled vertex array has no buffer and no pointer."));
1509b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                return false;
15102b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            }
15112b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        }
15122b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    }
15132b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
1514250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    // No-op if zero count
1515250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    return (count > 0);
1516250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill}
1517250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1518b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateDrawArrays(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
1519250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill{
1520fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    if (first < 0)
1521250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1522b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1523b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1524250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1525250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1526d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    const State &state = context->getState();
1527d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
1528250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() &&
1529250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        curTransformFeedback->getDrawMode() != mode)
1530250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1531250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
1532250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        // that does not match the current transform feedback object's draw mode (if transform feedback
1533250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        // is active), (3.0.2, section 2.14, pg 86)
1534b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1535b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1536250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1537250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1538b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang    if (!ValidateDrawBase(context, mode, count, count, primcount))
1539fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    {
1540fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill        return false;
1541fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    }
1542fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill
1543fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    return true;
1544250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill}
1545250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1546b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateDrawArraysInstanced(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
1547250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill{
1548fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    if (primcount < 0)
1549250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1550b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1551b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1552250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1553250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
15542b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    if (!ValidateDrawArrays(context, mode, first, count, primcount))
1555fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    {
1556fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill        return false;
1557fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    }
1558fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill
1559fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    // No-op if zero primitive count
1560fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    return (primcount > 0);
1561fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill}
1562fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill
156387a93308da237626325d13339565d7136125ed0dGeoff Langstatic bool ValidateDrawInstancedANGLE(Context *context)
156487a93308da237626325d13339565d7136125ed0dGeoff Lang{
156587a93308da237626325d13339565d7136125ed0dGeoff Lang    // Verify there is at least one active attribute with a divisor of zero
156687a93308da237626325d13339565d7136125ed0dGeoff Lang    const gl::State& state = context->getState();
156787a93308da237626325d13339565d7136125ed0dGeoff Lang
156887a93308da237626325d13339565d7136125ed0dGeoff Lang    gl::ProgramBinary *programBinary = state.getCurrentProgramBinary();
156987a93308da237626325d13339565d7136125ed0dGeoff Lang
157087a93308da237626325d13339565d7136125ed0dGeoff Lang    const VertexArray *vao = state.getVertexArray();
157187a93308da237626325d13339565d7136125ed0dGeoff Lang    for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
157287a93308da237626325d13339565d7136125ed0dGeoff Lang    {
157387a93308da237626325d13339565d7136125ed0dGeoff Lang        const VertexAttribute &attrib = vao->getVertexAttribute(attributeIndex);
157487a93308da237626325d13339565d7136125ed0dGeoff Lang        bool active = (programBinary->getSemanticIndex(attributeIndex) != -1);
157587a93308da237626325d13339565d7136125ed0dGeoff Lang        if (active && attrib.divisor == 0)
157687a93308da237626325d13339565d7136125ed0dGeoff Lang        {
157787a93308da237626325d13339565d7136125ed0dGeoff Lang            return true;
157887a93308da237626325d13339565d7136125ed0dGeoff Lang        }
157987a93308da237626325d13339565d7136125ed0dGeoff Lang    }
158087a93308da237626325d13339565d7136125ed0dGeoff Lang
158187a93308da237626325d13339565d7136125ed0dGeoff Lang    context->recordError(Error(GL_INVALID_OPERATION, "ANGLE_instanced_arrays requires that at least one active attribute"
158287a93308da237626325d13339565d7136125ed0dGeoff Lang                                                     "has a divisor of zero."));
158387a93308da237626325d13339565d7136125ed0dGeoff Lang    return false;
158487a93308da237626325d13339565d7136125ed0dGeoff Lang}
158587a93308da237626325d13339565d7136125ed0dGeoff Lang
158687a93308da237626325d13339565d7136125ed0dGeoff Langbool ValidateDrawArraysInstancedANGLE(Context *context, GLenum mode, GLint first, GLsizei count, GLsizei primcount)
158787a93308da237626325d13339565d7136125ed0dGeoff Lang{
158887a93308da237626325d13339565d7136125ed0dGeoff Lang    if (!ValidateDrawInstancedANGLE(context))
158987a93308da237626325d13339565d7136125ed0dGeoff Lang    {
159087a93308da237626325d13339565d7136125ed0dGeoff Lang        return false;
159187a93308da237626325d13339565d7136125ed0dGeoff Lang    }
159287a93308da237626325d13339565d7136125ed0dGeoff Lang
159387a93308da237626325d13339565d7136125ed0dGeoff Lang    return ValidateDrawArraysInstanced(context, mode, first, count, primcount);
159487a93308da237626325d13339565d7136125ed0dGeoff Lang}
159587a93308da237626325d13339565d7136125ed0dGeoff Lang
1596b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum type,
15972b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                          const GLvoid* indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
1598fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill{
1599250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    switch (type)
1600250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1601250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill      case GL_UNSIGNED_BYTE:
1602250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill      case GL_UNSIGNED_SHORT:
1603250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        break;
1604250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill      case GL_UNSIGNED_INT:
1605c0b9ef4bce04077046ca57b9bc249f26e42d07caGeoff Lang        if (!context->getExtensions().elementIndexUint)
1606250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        {
1607b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
1608b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1609250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        }
1610250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        break;
1611250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill      default:
1612b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1613b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1614250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1615250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1616d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    const State &state = context->getState();
1617d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill
1618d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    gl::TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
1619250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
1620250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1621250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced
1622250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill        // while transform feedback is active, (3.0.2, section 2.14, pg 86)
1623b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1624b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1625250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1626250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1627250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    // Check for mapped buffers
1628d9ba4f7318979e927c7a3320c5746c25381eae90Jamie Madill    if (state.hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER))
1629250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1630b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1631b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1632250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1633250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
16342b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    const gl::VertexArray *vao = state.getVertexArray();
16352b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    const gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
16362b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    if (!indices && !elementArrayBuffer)
1637d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill    {
1638b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1639b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1640d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill    }
1641d4cfa57df4df85546a969f66ec50d364f6e6d4feJamie Madill
1642ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill    if (elementArrayBuffer)
1643ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill    {
1644ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        const gl::Type &typeInfo = gl::GetTypeInfo(type);
1645ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill
1646ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        GLint64 offset = reinterpret_cast<GLint64>(indices);
1647ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        GLint64 byteCount = static_cast<GLint64>(typeInfo.bytes) * static_cast<GLint64>(count)+offset;
1648ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill
1649ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        // check for integer overflows
1650ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        if (static_cast<GLuint>(count) > (std::numeric_limits<GLuint>::max() / typeInfo.bytes) ||
1651ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill            byteCount > static_cast<GLint64>(std::numeric_limits<GLuint>::max()))
1652ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        {
1653b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_OUT_OF_MEMORY));
1654b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1655ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        }
1656ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill
1657ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        // Check for reading past the end of the bound buffer object
1658ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        if (byteCount > elementArrayBuffer->getSize())
1659ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        {
1660b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
1661b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
1662ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        }
1663ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill    }
1664ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill    else if (!indices)
1665ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill    {
1666ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill        // Catch this programming error here
1667b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1668b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1669ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill    }
1670ae3000b451de62a605415a5bebce2a9798e07399Jamie Madill
16712b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    // Use max index to validate if our vertex buffers are large enough for the pull.
16722b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    // TODO: offer fast path, with disabled index validation.
16732b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    // TODO: also disable index checking on back-ends that are robust to out-of-range accesses.
16742b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    if (elementArrayBuffer)
16752b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    {
16762b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        unsigned int offset = reinterpret_cast<unsigned int>(indices);
16772b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        if (!elementArrayBuffer->getIndexRangeCache()->findRange(type, offset, count, indexRangeOut, NULL))
16782b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        {
16792b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            const void *dataPointer = elementArrayBuffer->getImplementation()->getData();
16802b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            const uint8_t *offsetPointer = static_cast<const uint8_t *>(dataPointer) + offset;
16812b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill            *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, offsetPointer, count);
16822b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        }
16832b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    }
16842b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    else
16852b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    {
16862b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        *indexRangeOut = rx::IndexRangeCache::ComputeRange(type, indices, count);
16872b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    }
16882b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
1689b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang    if (!ValidateDrawBase(context, mode, count, static_cast<GLsizei>(indexRangeOut->end), primcount))
1690fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    {
1691fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill        return false;
1692fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    }
1693fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill
1694fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    return true;
1695250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill}
1696250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1697b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateDrawElementsInstanced(Context *context,
16982b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                                   GLenum mode, GLsizei count, GLenum type,
16992b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                                   const GLvoid *indices, GLsizei primcount,
17002b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill                                   rx::RangeUI *indexRangeOut)
1701250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill{
1702fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    if (primcount < 0)
1703250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1704b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1705b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1706250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1707250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
17082b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    if (!ValidateDrawElements(context, mode, count, type, indices, primcount, indexRangeOut))
1709250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    {
1710fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill        return false;
1711250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill    }
1712250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
1713fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    // No-op zero primitive count
1714fd716586aa61ca2875d7a04219a8c222cb5f69b0Jamie Madill    return (primcount > 0);
1715250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill}
1716250d33fb25761753061afd70f64aeff4ccecaa5bJamie Madill
171787a93308da237626325d13339565d7136125ed0dGeoff Langbool ValidateDrawElementsInstancedANGLE(Context *context, GLenum mode, GLsizei count, GLenum type,
171887a93308da237626325d13339565d7136125ed0dGeoff Lang                                        const GLvoid *indices, GLsizei primcount, rx::RangeUI *indexRangeOut)
171987a93308da237626325d13339565d7136125ed0dGeoff Lang{
172087a93308da237626325d13339565d7136125ed0dGeoff Lang    if (!ValidateDrawInstancedANGLE(context))
172187a93308da237626325d13339565d7136125ed0dGeoff Lang    {
172287a93308da237626325d13339565d7136125ed0dGeoff Lang        return false;
172387a93308da237626325d13339565d7136125ed0dGeoff Lang    }
172487a93308da237626325d13339565d7136125ed0dGeoff Lang
172587a93308da237626325d13339565d7136125ed0dGeoff Lang    return ValidateDrawElementsInstanced(context, mode, count, type, indices, primcount, indexRangeOut);
172687a93308da237626325d13339565d7136125ed0dGeoff Lang}
172787a93308da237626325d13339565d7136125ed0dGeoff Lang
1728b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateFramebufferTextureBase(Context *context, GLenum target, GLenum attachment,
172955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                                    GLuint texture, GLint level)
173055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill{
173155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (!ValidFramebufferTarget(target))
173255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    {
1733b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_ENUM));
1734b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
173555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    }
173655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
173755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (!ValidateAttachmentTarget(context, attachment))
173855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    {
173955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        return false;
174055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    }
174155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
174255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (texture != 0)
174355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    {
174455ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        gl::Texture *tex = context->getTexture(texture);
174555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
174655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        if (tex == NULL)
174755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        {
1748b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_OPERATION));
1749b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
175055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        }
175155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
175255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        if (level < 0)
175355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        {
1754b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_VALUE));
1755b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
175655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        }
175755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    }
175855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
175953a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    const gl::Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
176053a94a8238621e36e437975e7a17a91cf995aed9Shannon Woods    GLuint framebufferHandle = context->getState().getTargetFramebuffer(target)->id();
176155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
176255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (framebufferHandle == 0 || !framebuffer)
176355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    {
1764b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1765b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
176655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    }
176755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
176855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    return true;
176955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill}
177055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
1771b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateFramebufferTexture2D(Context *context, GLenum target, GLenum attachment,
1772570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill                                  GLenum textarget, GLuint texture, GLint level)
1773570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill{
177455ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    // Attachments are required to be bound to level 0 in ES2
177555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (context->getClientVersion() < 3 && level != 0)
1776570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill    {
1777b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1778b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1779570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill    }
1780570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill
178155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
1782570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill    {
1783570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill        return false;
1784570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill    }
1785570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill
178655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    if (texture != 0)
178755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    {
178855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        gl::Texture *tex = context->getTexture(texture);
178955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        ASSERT(tex);
179055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
17912a6564eb7314c6da27d8d21c5a068034d251d028Jamie Madill        const gl::Caps &caps = context->getCaps();
17922a6564eb7314c6da27d8d21c5a068034d251d028Jamie Madill
179355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        switch (textarget)
179455ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        {
179555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_2D:
179655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill            {
17972a6564eb7314c6da27d8d21c5a068034d251d028Jamie Madill                if (level > gl::log2(caps.max2DTextureSize))
179855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                {
1799b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_VALUE));
1800b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
180155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                }
180255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                if (tex->getTarget() != GL_TEXTURE_2D)
180355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                {
1804b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
1805b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
180655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                }
180755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
180855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                if (tex2d->isCompressed(level))
180955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                {
1810b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
1811b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
181255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                }
181355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill            }
181455ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill            break;
181555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
181655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
181755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
181855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
181955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
182055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
182155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
182255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill            {
18232a6564eb7314c6da27d8d21c5a068034d251d028Jamie Madill                if (level > gl::log2(caps.maxCubeMapTextureSize))
182455ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                {
1825b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_VALUE));
1826b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
182755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                }
182855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
182955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                {
1830b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
1831b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
183255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                }
183355ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
183455ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                if (texcube->isCompressed(textarget, level))
183555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                {
1836b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    context->recordError(Error(GL_INVALID_OPERATION));
1837b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang                    return false;
183855ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill                }
183955ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill            }
184055ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill            break;
184155ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
184255ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill          default:
1843b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            context->recordError(Error(GL_INVALID_ENUM));
1844b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang            return false;
184555ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill        }
184655ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill    }
184755ec3b111464887e6e3ab1df848cf73509cde418Jamie Madill
1848570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill    return true;
1849570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill}
1850570f7c84a7d353c99f7c001af3b7b73e21b316fbJamie Madill
1851b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
18520063c51742659230ce535eb270acc0f06921d754Jamie Madill{
18530063c51742659230ce535eb270acc0f06921d754Jamie Madill    if (program == 0)
18540063c51742659230ce535eb270acc0f06921d754Jamie Madill    {
1855b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_VALUE));
1856b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
18570063c51742659230ce535eb270acc0f06921d754Jamie Madill    }
18580063c51742659230ce535eb270acc0f06921d754Jamie Madill
18590063c51742659230ce535eb270acc0f06921d754Jamie Madill    gl::Program *programObject = context->getProgram(program);
18600063c51742659230ce535eb270acc0f06921d754Jamie Madill
18610063c51742659230ce535eb270acc0f06921d754Jamie Madill    if (!programObject || !programObject->isLinked())
18620063c51742659230ce535eb270acc0f06921d754Jamie Madill    {
1863b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1864b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
18650063c51742659230ce535eb270acc0f06921d754Jamie Madill    }
18660063c51742659230ce535eb270acc0f06921d754Jamie Madill
18670063c51742659230ce535eb270acc0f06921d754Jamie Madill    gl::ProgramBinary *programBinary = programObject->getProgramBinary();
18680063c51742659230ce535eb270acc0f06921d754Jamie Madill    if (!programBinary)
18690063c51742659230ce535eb270acc0f06921d754Jamie Madill    {
1870b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1871b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
18720063c51742659230ce535eb270acc0f06921d754Jamie Madill    }
18730063c51742659230ce535eb270acc0f06921d754Jamie Madill
1874549c7fdf998599a105c17c5e2456554dd3e142bbJamie Madill    if (!programBinary->isValidUniformLocation(location))
1875549c7fdf998599a105c17c5e2456554dd3e142bbJamie Madill    {
1876b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1877b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
1878549c7fdf998599a105c17c5e2456554dd3e142bbJamie Madill    }
1879549c7fdf998599a105c17c5e2456554dd3e142bbJamie Madill
18800063c51742659230ce535eb270acc0f06921d754Jamie Madill    return true;
18810063c51742659230ce535eb270acc0f06921d754Jamie Madill}
18820063c51742659230ce535eb270acc0f06921d754Jamie Madill
1883b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat* params)
18840063c51742659230ce535eb270acc0f06921d754Jamie Madill{
188578f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill    return ValidateGetUniformBase(context, program, location);
18860063c51742659230ce535eb270acc0f06921d754Jamie Madill}
18870063c51742659230ce535eb270acc0f06921d754Jamie Madill
1888b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint* params)
18890063c51742659230ce535eb270acc0f06921d754Jamie Madill{
189078f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill    return ValidateGetUniformBase(context, program, location);
189178f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill}
18920063c51742659230ce535eb270acc0f06921d754Jamie Madill
1893b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langstatic bool ValidateSizedGetUniform(Context *context, GLuint program, GLint location, GLsizei bufSize)
189478f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill{
189578f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill    if (!ValidateGetUniformBase(context, program, location))
18960063c51742659230ce535eb270acc0f06921d754Jamie Madill    {
189778f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill        return false;
18980063c51742659230ce535eb270acc0f06921d754Jamie Madill    }
18990063c51742659230ce535eb270acc0f06921d754Jamie Madill
1900a502c749b249df6460326c4e5354f0549cc698d8Jamie Madill    gl::Program *programObject = context->getProgram(program);
1901a502c749b249df6460326c4e5354f0549cc698d8Jamie Madill    ASSERT(programObject);
1902a502c749b249df6460326c4e5354f0549cc698d8Jamie Madill    gl::ProgramBinary *programBinary = programObject->getProgramBinary();
19030063c51742659230ce535eb270acc0f06921d754Jamie Madill
190499a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    // sized queries -- ensure the provided buffer is large enough
190599a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    LinkedUniform *uniform = programBinary->getUniformByLocation(location);
190699a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    size_t requiredBytes = VariableExternalSize(uniform->type);
190799a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    if (static_cast<size_t>(bufSize) < requiredBytes)
190899a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    {
1909b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        context->recordError(Error(GL_INVALID_OPERATION));
1910b119668772ee960d8fc9e3846617c59530b90d5fGeoff Lang        return false;
191199a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill    }
191299a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill
19130063c51742659230ce535eb270acc0f06921d754Jamie Madill    return true;
19140063c51742659230ce535eb270acc0f06921d754Jamie Madill}
19150063c51742659230ce535eb270acc0f06921d754Jamie Madill
1916b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateGetnUniformfvEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
19170063c51742659230ce535eb270acc0f06921d754Jamie Madill{
191878f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill    return ValidateSizedGetUniform(context, program, location, bufSize);
191978f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill}
192099a1e985196cab0ab309209fe8319f6bdbe1dd20Jamie Madill
1921b119668772ee960d8fc9e3846617c59530b90d5fGeoff Langbool ValidateGetnUniformivEXT(Context *context, GLuint program, GLint location, GLsizei bufSize, GLint* params)
192278f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill{
192378f4180564b36fbb3ab21f298b12e2a1c8b18fcfJamie Madill    return ValidateSizedGetUniform(context, program, location, bufSize);
19240063c51742659230ce535eb270acc0f06921d754Jamie Madill}
19250063c51742659230ce535eb270acc0f06921d754Jamie Madill
1926e8ebe7f6ec21c3e624998d6fc1d10d1dbf6103c9Geoff Lang}
1927