1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // validationES.h: Validation functions for generic OpenGL ES entry point parameters
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationES.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ErrorStrings.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Framebuffer.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/FramebufferAttachment.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/PixelLocalStorage.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Program.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Query.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Texture.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/TransformFeedback.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/queryconversions.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/queryutils.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationES2.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationES3.h"
28*8975f5c5SAndroid Build Coastguard Worker
29*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
31*8975f5c5SAndroid Build Coastguard Worker
32*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker namespace gl
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker using namespace err;
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker namespace
39*8975f5c5SAndroid Build Coastguard Worker {
CompressedTextureFormatRequiresExactSize(GLenum internalFormat)40*8975f5c5SAndroid Build Coastguard Worker bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker // List of compressed format that require that the texture size is smaller than or a multiple of
43*8975f5c5SAndroid Build Coastguard Worker // the compressed block size.
44*8975f5c5SAndroid Build Coastguard Worker switch (internalFormat)
45*8975f5c5SAndroid Build Coastguard Worker {
46*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
47*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
48*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
49*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
50*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
51*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
52*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
53*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
54*8975f5c5SAndroid Build Coastguard Worker case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
55*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
56*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
57*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
58*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
59*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
60*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
61*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_RGTC1_EXT:
62*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
63*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
64*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
65*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
66*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
67*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
68*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
69*8975f5c5SAndroid Build Coastguard Worker return true;
70*8975f5c5SAndroid Build Coastguard Worker
71*8975f5c5SAndroid Build Coastguard Worker default:
72*8975f5c5SAndroid Build Coastguard Worker return false;
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker }
75*8975f5c5SAndroid Build Coastguard Worker
DifferenceCanOverflow(GLint a,GLint b)76*8975f5c5SAndroid Build Coastguard Worker bool DifferenceCanOverflow(GLint a, GLint b)
77*8975f5c5SAndroid Build Coastguard Worker {
78*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<GLint> checkedA(a);
79*8975f5c5SAndroid Build Coastguard Worker checkedA -= b;
80*8975f5c5SAndroid Build Coastguard Worker // Use negation to make sure that the difference can't overflow regardless of the order.
81*8975f5c5SAndroid Build Coastguard Worker checkedA = -checkedA;
82*8975f5c5SAndroid Build Coastguard Worker return !checkedA.IsValid();
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker
ValidReadPixelsTypeEnum(const Context * context,GLenum type)85*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsTypeEnum(const Context *context, GLenum type)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker switch (type)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker // Types referenced in Table 3.4 of the ES 2.0.25 spec
90*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_BYTE:
91*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT_4_4_4_4:
92*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT_5_5_5_1:
93*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT_5_6_5:
94*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_2_0;
95*8975f5c5SAndroid Build Coastguard Worker
96*8975f5c5SAndroid Build Coastguard Worker // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
97*8975f5c5SAndroid Build Coastguard Worker case GL_BYTE:
98*8975f5c5SAndroid Build Coastguard Worker case GL_INT:
99*8975f5c5SAndroid Build Coastguard Worker case GL_SHORT:
100*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
101*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_10F_11F_11F_REV:
102*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_2_10_10_10_REV:
103*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_5_9_9_9_REV:
104*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT:
105*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
106*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
107*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0;
108*8975f5c5SAndroid Build Coastguard Worker
109*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT:
110*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0 ||
111*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureFloatOES ||
112*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().colorBufferHalfFloatEXT;
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker case GL_HALF_FLOAT:
115*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0 ||
116*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureHalfFloatOES;
117*8975f5c5SAndroid Build Coastguard Worker
118*8975f5c5SAndroid Build Coastguard Worker case GL_HALF_FLOAT_OES:
119*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().colorBufferHalfFloatEXT;
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker default:
122*8975f5c5SAndroid Build Coastguard Worker return false;
123*8975f5c5SAndroid Build Coastguard Worker }
124*8975f5c5SAndroid Build Coastguard Worker }
125*8975f5c5SAndroid Build Coastguard Worker
ValidReadPixelsFormatEnum(const Context * context,GLenum format)126*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsFormatEnum(const Context *context, GLenum format)
127*8975f5c5SAndroid Build Coastguard Worker {
128*8975f5c5SAndroid Build Coastguard Worker switch (format)
129*8975f5c5SAndroid Build Coastguard Worker {
130*8975f5c5SAndroid Build Coastguard Worker // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
131*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA:
132*8975f5c5SAndroid Build Coastguard Worker case GL_RGB:
133*8975f5c5SAndroid Build Coastguard Worker case GL_ALPHA:
134*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_2_0;
135*8975f5c5SAndroid Build Coastguard Worker
136*8975f5c5SAndroid Build Coastguard Worker // Formats referenced in Table 3.2 of the ES 3.0.5 spec
137*8975f5c5SAndroid Build Coastguard Worker case GL_RG:
138*8975f5c5SAndroid Build Coastguard Worker case GL_RED:
139*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA_INTEGER:
140*8975f5c5SAndroid Build Coastguard Worker case GL_RGB_INTEGER:
141*8975f5c5SAndroid Build Coastguard Worker case GL_RG_INTEGER:
142*8975f5c5SAndroid Build Coastguard Worker case GL_RED_INTEGER:
143*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0;
144*8975f5c5SAndroid Build Coastguard Worker
145*8975f5c5SAndroid Build Coastguard Worker case GL_SRGB_ALPHA_EXT:
146*8975f5c5SAndroid Build Coastguard Worker case GL_SRGB_EXT:
147*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().sRGBEXT;
148*8975f5c5SAndroid Build Coastguard Worker
149*8975f5c5SAndroid Build Coastguard Worker case GL_BGRA_EXT:
150*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().readFormatBgraEXT;
151*8975f5c5SAndroid Build Coastguard Worker
152*8975f5c5SAndroid Build Coastguard Worker case GL_RGBX8_ANGLE:
153*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().rgbxInternalFormatANGLE;
154*8975f5c5SAndroid Build Coastguard Worker
155*8975f5c5SAndroid Build Coastguard Worker default:
156*8975f5c5SAndroid Build Coastguard Worker return false;
157*8975f5c5SAndroid Build Coastguard Worker }
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker
ValidReadPixelsUnsignedNormalizedDepthType(const Context * context,const gl::InternalFormat * info,GLenum type)160*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsUnsignedNormalizedDepthType(const Context *context,
161*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat *info,
162*8975f5c5SAndroid Build Coastguard Worker GLenum type)
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker bool supportsReadDepthNV = context->getExtensions().readDepthNV && (info->depthBits > 0);
165*8975f5c5SAndroid Build Coastguard Worker switch (type)
166*8975f5c5SAndroid Build Coastguard Worker {
167*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_SHORT:
168*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
169*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_24_8:
170*8975f5c5SAndroid Build Coastguard Worker return supportsReadDepthNV;
171*8975f5c5SAndroid Build Coastguard Worker default:
172*8975f5c5SAndroid Build Coastguard Worker return false;
173*8975f5c5SAndroid Build Coastguard Worker }
174*8975f5c5SAndroid Build Coastguard Worker }
175*8975f5c5SAndroid Build Coastguard Worker
ValidReadPixelsFloatDepthType(const Context * context,const gl::InternalFormat * info,GLenum type)176*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsFloatDepthType(const Context *context,
177*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat *info,
178*8975f5c5SAndroid Build Coastguard Worker GLenum type)
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().readDepthNV && (type == GL_FLOAT) &&
181*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().depthBufferFloat2NV;
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker
ValidReadPixelsFormatType(const Context * context,const gl::InternalFormat * info,GLenum format,GLenum type)184*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsFormatType(const Context *context,
185*8975f5c5SAndroid Build Coastguard Worker const gl::InternalFormat *info,
186*8975f5c5SAndroid Build Coastguard Worker GLenum format,
187*8975f5c5SAndroid Build Coastguard Worker GLenum type)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker switch (info->componentType)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_NORMALIZED:
192*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
193*8975f5c5SAndroid Build Coastguard Worker // ReadPixels with BGRA even if the extension is not present
194*8975f5c5SAndroid Build Coastguard Worker switch (format)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA:
197*8975f5c5SAndroid Build Coastguard Worker return type == GL_UNSIGNED_BYTE ||
198*8975f5c5SAndroid Build Coastguard Worker (context->getExtensions().textureNorm16EXT &&
199*8975f5c5SAndroid Build Coastguard Worker type == GL_UNSIGNED_SHORT && info->type == GL_UNSIGNED_SHORT);
200*8975f5c5SAndroid Build Coastguard Worker case GL_BGRA_EXT:
201*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().readFormatBgraEXT && (type == GL_UNSIGNED_BYTE);
202*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_INDEX_OES:
203*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().readStencilNV && (type == GL_UNSIGNED_BYTE);
204*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
205*8975f5c5SAndroid Build Coastguard Worker return ValidReadPixelsUnsignedNormalizedDepthType(context, info, type);
206*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_OES:
207*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().readDepthStencilNV &&
208*8975f5c5SAndroid Build Coastguard Worker (type == GL_UNSIGNED_INT_24_8_OES) && info->stencilBits > 0;
209*8975f5c5SAndroid Build Coastguard Worker case GL_RGBX8_ANGLE:
210*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().rgbxInternalFormatANGLE &&
211*8975f5c5SAndroid Build Coastguard Worker (type == GL_UNSIGNED_BYTE);
212*8975f5c5SAndroid Build Coastguard Worker default:
213*8975f5c5SAndroid Build Coastguard Worker return false;
214*8975f5c5SAndroid Build Coastguard Worker }
215*8975f5c5SAndroid Build Coastguard Worker case GL_SIGNED_NORMALIZED:
216*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getExtensions().renderSnormEXT);
217*8975f5c5SAndroid Build Coastguard Worker ASSERT(info->type == GL_BYTE ||
218*8975f5c5SAndroid Build Coastguard Worker (context->getExtensions().textureNorm16EXT && info->type == GL_SHORT));
219*8975f5c5SAndroid Build Coastguard Worker // Type conversions are not allowed for signed normalized color buffers
220*8975f5c5SAndroid Build Coastguard Worker return format == GL_RGBA && type == info->type;
221*8975f5c5SAndroid Build Coastguard Worker
222*8975f5c5SAndroid Build Coastguard Worker case GL_INT:
223*8975f5c5SAndroid Build Coastguard Worker return (format == GL_RGBA_INTEGER && type == GL_INT);
224*8975f5c5SAndroid Build Coastguard Worker
225*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT:
226*8975f5c5SAndroid Build Coastguard Worker return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
227*8975f5c5SAndroid Build Coastguard Worker
228*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT:
229*8975f5c5SAndroid Build Coastguard Worker switch (format)
230*8975f5c5SAndroid Build Coastguard Worker {
231*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA:
232*8975f5c5SAndroid Build Coastguard Worker return (type == GL_FLOAT);
233*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
234*8975f5c5SAndroid Build Coastguard Worker return ValidReadPixelsFloatDepthType(context, info, type);
235*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_OES:
236*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().readDepthStencilNV &&
237*8975f5c5SAndroid Build Coastguard Worker type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && info->stencilBits > 0;
238*8975f5c5SAndroid Build Coastguard Worker default:
239*8975f5c5SAndroid Build Coastguard Worker return false;
240*8975f5c5SAndroid Build Coastguard Worker }
241*8975f5c5SAndroid Build Coastguard Worker default:
242*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
243*8975f5c5SAndroid Build Coastguard Worker return false;
244*8975f5c5SAndroid Build Coastguard Worker }
245*8975f5c5SAndroid Build Coastguard Worker }
246*8975f5c5SAndroid Build Coastguard Worker
247*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureWrapModeValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params,bool restrictedWrapModes)248*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureWrapModeValue(const Context *context,
249*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
250*8975f5c5SAndroid Build Coastguard Worker const ParamType *params,
251*8975f5c5SAndroid Build Coastguard Worker bool restrictedWrapModes)
252*8975f5c5SAndroid Build Coastguard Worker {
253*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker case GL_CLAMP_TO_EDGE:
256*8975f5c5SAndroid Build Coastguard Worker break;
257*8975f5c5SAndroid Build Coastguard Worker
258*8975f5c5SAndroid Build Coastguard Worker case GL_CLAMP_TO_BORDER:
259*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureBorderClampAny() &&
260*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
261*8975f5c5SAndroid Build Coastguard Worker {
262*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
263*8975f5c5SAndroid Build Coastguard Worker return false;
264*8975f5c5SAndroid Build Coastguard Worker }
265*8975f5c5SAndroid Build Coastguard Worker if (restrictedWrapModes)
266*8975f5c5SAndroid Build Coastguard Worker {
267*8975f5c5SAndroid Build Coastguard Worker // OES_EGL_image_external and ANGLE_texture_rectangle specify this error.
268*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidWrapModeTexture);
269*8975f5c5SAndroid Build Coastguard Worker return false;
270*8975f5c5SAndroid Build Coastguard Worker }
271*8975f5c5SAndroid Build Coastguard Worker break;
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker case GL_REPEAT:
274*8975f5c5SAndroid Build Coastguard Worker case GL_MIRRORED_REPEAT:
275*8975f5c5SAndroid Build Coastguard Worker if (restrictedWrapModes)
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker // OES_EGL_image_external and ANGLE_texture_rectangle specify this error.
278*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidWrapModeTexture);
279*8975f5c5SAndroid Build Coastguard Worker return false;
280*8975f5c5SAndroid Build Coastguard Worker }
281*8975f5c5SAndroid Build Coastguard Worker break;
282*8975f5c5SAndroid Build Coastguard Worker
283*8975f5c5SAndroid Build Coastguard Worker case GL_MIRROR_CLAMP_TO_EDGE_EXT:
284*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureMirrorClampToEdgeEXT)
285*8975f5c5SAndroid Build Coastguard Worker {
286*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
287*8975f5c5SAndroid Build Coastguard Worker return false;
288*8975f5c5SAndroid Build Coastguard Worker }
289*8975f5c5SAndroid Build Coastguard Worker if (restrictedWrapModes)
290*8975f5c5SAndroid Build Coastguard Worker {
291*8975f5c5SAndroid Build Coastguard Worker // OES_EGL_image_external and ANGLE_texture_rectangle specify this error.
292*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidWrapModeTexture);
293*8975f5c5SAndroid Build Coastguard Worker return false;
294*8975f5c5SAndroid Build Coastguard Worker }
295*8975f5c5SAndroid Build Coastguard Worker break;
296*8975f5c5SAndroid Build Coastguard Worker
297*8975f5c5SAndroid Build Coastguard Worker default:
298*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureWrap);
299*8975f5c5SAndroid Build Coastguard Worker return false;
300*8975f5c5SAndroid Build Coastguard Worker }
301*8975f5c5SAndroid Build Coastguard Worker
302*8975f5c5SAndroid Build Coastguard Worker return true;
303*8975f5c5SAndroid Build Coastguard Worker }
304*8975f5c5SAndroid Build Coastguard Worker
305*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureMinFilterValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params,bool restrictedMinFilter)306*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMinFilterValue(const Context *context,
307*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
308*8975f5c5SAndroid Build Coastguard Worker const ParamType *params,
309*8975f5c5SAndroid Build Coastguard Worker bool restrictedMinFilter)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
312*8975f5c5SAndroid Build Coastguard Worker {
313*8975f5c5SAndroid Build Coastguard Worker case GL_NEAREST:
314*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR:
315*8975f5c5SAndroid Build Coastguard Worker break;
316*8975f5c5SAndroid Build Coastguard Worker
317*8975f5c5SAndroid Build Coastguard Worker case GL_NEAREST_MIPMAP_NEAREST:
318*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR_MIPMAP_NEAREST:
319*8975f5c5SAndroid Build Coastguard Worker case GL_NEAREST_MIPMAP_LINEAR:
320*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR_MIPMAP_LINEAR:
321*8975f5c5SAndroid Build Coastguard Worker if (restrictedMinFilter)
322*8975f5c5SAndroid Build Coastguard Worker {
323*8975f5c5SAndroid Build Coastguard Worker // OES_EGL_image_external specifies this error.
324*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFilterTexture);
325*8975f5c5SAndroid Build Coastguard Worker return false;
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker break;
328*8975f5c5SAndroid Build Coastguard Worker
329*8975f5c5SAndroid Build Coastguard Worker default:
330*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureFilterParam);
331*8975f5c5SAndroid Build Coastguard Worker return false;
332*8975f5c5SAndroid Build Coastguard Worker }
333*8975f5c5SAndroid Build Coastguard Worker
334*8975f5c5SAndroid Build Coastguard Worker return true;
335*8975f5c5SAndroid Build Coastguard Worker }
336*8975f5c5SAndroid Build Coastguard Worker
337*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureMagFilterValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)338*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMagFilterValue(const Context *context,
339*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
340*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
341*8975f5c5SAndroid Build Coastguard Worker {
342*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker case GL_NEAREST:
345*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR:
346*8975f5c5SAndroid Build Coastguard Worker break;
347*8975f5c5SAndroid Build Coastguard Worker
348*8975f5c5SAndroid Build Coastguard Worker default:
349*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureFilterParam);
350*8975f5c5SAndroid Build Coastguard Worker return false;
351*8975f5c5SAndroid Build Coastguard Worker }
352*8975f5c5SAndroid Build Coastguard Worker
353*8975f5c5SAndroid Build Coastguard Worker return true;
354*8975f5c5SAndroid Build Coastguard Worker }
355*8975f5c5SAndroid Build Coastguard Worker
356*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureCompareModeValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)357*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureCompareModeValue(const Context *context,
358*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
359*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
360*8975f5c5SAndroid Build Coastguard Worker {
361*8975f5c5SAndroid Build Coastguard Worker // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
362*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
363*8975f5c5SAndroid Build Coastguard Worker {
364*8975f5c5SAndroid Build Coastguard Worker case GL_NONE:
365*8975f5c5SAndroid Build Coastguard Worker case GL_COMPARE_REF_TO_TEXTURE:
366*8975f5c5SAndroid Build Coastguard Worker break;
367*8975f5c5SAndroid Build Coastguard Worker
368*8975f5c5SAndroid Build Coastguard Worker default:
369*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
370*8975f5c5SAndroid Build Coastguard Worker return false;
371*8975f5c5SAndroid Build Coastguard Worker }
372*8975f5c5SAndroid Build Coastguard Worker
373*8975f5c5SAndroid Build Coastguard Worker return true;
374*8975f5c5SAndroid Build Coastguard Worker }
375*8975f5c5SAndroid Build Coastguard Worker
376*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureCompareFuncValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)377*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureCompareFuncValue(const Context *context,
378*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
379*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
380*8975f5c5SAndroid Build Coastguard Worker {
381*8975f5c5SAndroid Build Coastguard Worker // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
382*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
383*8975f5c5SAndroid Build Coastguard Worker {
384*8975f5c5SAndroid Build Coastguard Worker case GL_LEQUAL:
385*8975f5c5SAndroid Build Coastguard Worker case GL_GEQUAL:
386*8975f5c5SAndroid Build Coastguard Worker case GL_LESS:
387*8975f5c5SAndroid Build Coastguard Worker case GL_GREATER:
388*8975f5c5SAndroid Build Coastguard Worker case GL_EQUAL:
389*8975f5c5SAndroid Build Coastguard Worker case GL_NOTEQUAL:
390*8975f5c5SAndroid Build Coastguard Worker case GL_ALWAYS:
391*8975f5c5SAndroid Build Coastguard Worker case GL_NEVER:
392*8975f5c5SAndroid Build Coastguard Worker break;
393*8975f5c5SAndroid Build Coastguard Worker
394*8975f5c5SAndroid Build Coastguard Worker default:
395*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
396*8975f5c5SAndroid Build Coastguard Worker return false;
397*8975f5c5SAndroid Build Coastguard Worker }
398*8975f5c5SAndroid Build Coastguard Worker
399*8975f5c5SAndroid Build Coastguard Worker return true;
400*8975f5c5SAndroid Build Coastguard Worker }
401*8975f5c5SAndroid Build Coastguard Worker
402*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureSRGBDecodeValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)403*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureSRGBDecodeValue(const Context *context,
404*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
405*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureSRGBDecodeEXT)
408*8975f5c5SAndroid Build Coastguard Worker {
409*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
410*8975f5c5SAndroid Build Coastguard Worker return false;
411*8975f5c5SAndroid Build Coastguard Worker }
412*8975f5c5SAndroid Build Coastguard Worker
413*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
414*8975f5c5SAndroid Build Coastguard Worker {
415*8975f5c5SAndroid Build Coastguard Worker case GL_DECODE_EXT:
416*8975f5c5SAndroid Build Coastguard Worker case GL_SKIP_DECODE_EXT:
417*8975f5c5SAndroid Build Coastguard Worker break;
418*8975f5c5SAndroid Build Coastguard Worker
419*8975f5c5SAndroid Build Coastguard Worker default:
420*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
421*8975f5c5SAndroid Build Coastguard Worker return false;
422*8975f5c5SAndroid Build Coastguard Worker }
423*8975f5c5SAndroid Build Coastguard Worker
424*8975f5c5SAndroid Build Coastguard Worker return true;
425*8975f5c5SAndroid Build Coastguard Worker }
426*8975f5c5SAndroid Build Coastguard Worker
427*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureSRGBOverrideValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)428*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureSRGBOverrideValue(const Context *context,
429*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
430*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
431*8975f5c5SAndroid Build Coastguard Worker {
432*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureFormatSRGBOverrideEXT)
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
435*8975f5c5SAndroid Build Coastguard Worker return false;
436*8975f5c5SAndroid Build Coastguard Worker }
437*8975f5c5SAndroid Build Coastguard Worker
438*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
439*8975f5c5SAndroid Build Coastguard Worker {
440*8975f5c5SAndroid Build Coastguard Worker case GL_SRGB:
441*8975f5c5SAndroid Build Coastguard Worker case GL_NONE:
442*8975f5c5SAndroid Build Coastguard Worker break;
443*8975f5c5SAndroid Build Coastguard Worker
444*8975f5c5SAndroid Build Coastguard Worker default:
445*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
446*8975f5c5SAndroid Build Coastguard Worker return false;
447*8975f5c5SAndroid Build Coastguard Worker }
448*8975f5c5SAndroid Build Coastguard Worker
449*8975f5c5SAndroid Build Coastguard Worker return true;
450*8975f5c5SAndroid Build Coastguard Worker }
451*8975f5c5SAndroid Build Coastguard Worker
ValidateTextureMaxAnisotropyExtensionEnabled(const Context * context,angle::EntryPoint entryPoint)452*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMaxAnisotropyExtensionEnabled(const Context *context,
453*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint)
454*8975f5c5SAndroid Build Coastguard Worker {
455*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureFilterAnisotropicEXT)
456*8975f5c5SAndroid Build Coastguard Worker {
457*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
458*8975f5c5SAndroid Build Coastguard Worker return false;
459*8975f5c5SAndroid Build Coastguard Worker }
460*8975f5c5SAndroid Build Coastguard Worker
461*8975f5c5SAndroid Build Coastguard Worker return true;
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker
ValidateTextureMaxAnisotropyValue(const Context * context,angle::EntryPoint entryPoint,GLfloat paramValue)464*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMaxAnisotropyValue(const Context *context,
465*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
466*8975f5c5SAndroid Build Coastguard Worker GLfloat paramValue)
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
469*8975f5c5SAndroid Build Coastguard Worker {
470*8975f5c5SAndroid Build Coastguard Worker return false;
471*8975f5c5SAndroid Build Coastguard Worker }
472*8975f5c5SAndroid Build Coastguard Worker
473*8975f5c5SAndroid Build Coastguard Worker GLfloat largest = context->getCaps().maxTextureAnisotropy;
474*8975f5c5SAndroid Build Coastguard Worker
475*8975f5c5SAndroid Build Coastguard Worker if (paramValue < 1 || paramValue > largest)
476*8975f5c5SAndroid Build Coastguard Worker {
477*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOutsideOfBounds);
478*8975f5c5SAndroid Build Coastguard Worker return false;
479*8975f5c5SAndroid Build Coastguard Worker }
480*8975f5c5SAndroid Build Coastguard Worker
481*8975f5c5SAndroid Build Coastguard Worker return true;
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker
ValidateFragmentShaderColorBufferMaskMatch(const Context * context)484*8975f5c5SAndroid Build Coastguard Worker bool ValidateFragmentShaderColorBufferMaskMatch(const Context *context)
485*8975f5c5SAndroid Build Coastguard Worker {
486*8975f5c5SAndroid Build Coastguard Worker const auto &glState = context->getState();
487*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
488*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = glState.getDrawFramebuffer();
489*8975f5c5SAndroid Build Coastguard Worker
490*8975f5c5SAndroid Build Coastguard Worker const auto &blendStateExt = glState.getBlendStateExt();
491*8975f5c5SAndroid Build Coastguard Worker auto drawBufferMask = framebuffer->getDrawBufferMask() & blendStateExt.compareColorMask(0);
492*8975f5c5SAndroid Build Coastguard Worker auto dualSourceBlendingMask = drawBufferMask & blendStateExt.getEnabledMask() &
493*8975f5c5SAndroid Build Coastguard Worker blendStateExt.getUsesExtendedBlendFactorMask();
494*8975f5c5SAndroid Build Coastguard Worker auto fragmentOutputMask = executable->getActiveOutputVariablesMask();
495*8975f5c5SAndroid Build Coastguard Worker auto fragmentSecondaryOutputMask = executable->getActiveSecondaryOutputVariablesMask();
496*8975f5c5SAndroid Build Coastguard Worker
497*8975f5c5SAndroid Build Coastguard Worker return drawBufferMask == (drawBufferMask & fragmentOutputMask) &&
498*8975f5c5SAndroid Build Coastguard Worker dualSourceBlendingMask == (dualSourceBlendingMask & fragmentSecondaryOutputMask);
499*8975f5c5SAndroid Build Coastguard Worker }
500*8975f5c5SAndroid Build Coastguard Worker
ValidateFragmentShaderColorBufferTypeMatch(const Context * context)501*8975f5c5SAndroid Build Coastguard Worker bool ValidateFragmentShaderColorBufferTypeMatch(const Context *context)
502*8975f5c5SAndroid Build Coastguard Worker {
503*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
504*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
505*8975f5c5SAndroid Build Coastguard Worker
506*8975f5c5SAndroid Build Coastguard Worker return ValidateComponentTypeMasks(executable->getFragmentOutputsTypeMask().to_ulong(),
507*8975f5c5SAndroid Build Coastguard Worker framebuffer->getDrawBufferTypeMask().to_ulong(),
508*8975f5c5SAndroid Build Coastguard Worker executable->getActiveOutputVariablesMask().to_ulong(),
509*8975f5c5SAndroid Build Coastguard Worker framebuffer->getDrawBufferMask().to_ulong());
510*8975f5c5SAndroid Build Coastguard Worker }
511*8975f5c5SAndroid Build Coastguard Worker
ValidateVertexShaderAttributeTypeMatch(const Context * context)512*8975f5c5SAndroid Build Coastguard Worker bool ValidateVertexShaderAttributeTypeMatch(const Context *context)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker const auto &glState = context->getState();
515*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
516*8975f5c5SAndroid Build Coastguard Worker const VertexArray *vao = context->getState().getVertexArray();
517*8975f5c5SAndroid Build Coastguard Worker
518*8975f5c5SAndroid Build Coastguard Worker if (executable == nullptr)
519*8975f5c5SAndroid Build Coastguard Worker {
520*8975f5c5SAndroid Build Coastguard Worker return false;
521*8975f5c5SAndroid Build Coastguard Worker }
522*8975f5c5SAndroid Build Coastguard Worker
523*8975f5c5SAndroid Build Coastguard Worker unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
524*8975f5c5SAndroid Build Coastguard Worker unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
525*8975f5c5SAndroid Build Coastguard Worker unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
526*8975f5c5SAndroid Build Coastguard Worker
527*8975f5c5SAndroid Build Coastguard Worker vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex;
528*8975f5c5SAndroid Build Coastguard Worker vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
529*8975f5c5SAndroid Build Coastguard Worker vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
530*8975f5c5SAndroid Build Coastguard Worker
531*8975f5c5SAndroid Build Coastguard Worker return ValidateComponentTypeMasks(executable->getAttributesTypeMask().to_ulong(),
532*8975f5c5SAndroid Build Coastguard Worker vaoAttribTypeBits, executable->getAttributesMask().to_ulong(),
533*8975f5c5SAndroid Build Coastguard Worker 0xFFFF);
534*8975f5c5SAndroid Build Coastguard Worker }
535*8975f5c5SAndroid Build Coastguard Worker
IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,PrimitiveMode geometryShaderInputPrimitiveType)536*8975f5c5SAndroid Build Coastguard Worker bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
537*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode geometryShaderInputPrimitiveType)
538*8975f5c5SAndroid Build Coastguard Worker {
539*8975f5c5SAndroid Build Coastguard Worker // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
540*8975f5c5SAndroid Build Coastguard Worker switch (drawMode)
541*8975f5c5SAndroid Build Coastguard Worker {
542*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Points:
543*8975f5c5SAndroid Build Coastguard Worker return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
544*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Lines:
545*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineStrip:
546*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineLoop:
547*8975f5c5SAndroid Build Coastguard Worker return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
548*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LinesAdjacency:
549*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineStripAdjacency:
550*8975f5c5SAndroid Build Coastguard Worker return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
551*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Triangles:
552*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleFan:
553*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleStrip:
554*8975f5c5SAndroid Build Coastguard Worker return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
555*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TrianglesAdjacency:
556*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleStripAdjacency:
557*8975f5c5SAndroid Build Coastguard Worker return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
558*8975f5c5SAndroid Build Coastguard Worker default:
559*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
560*8975f5c5SAndroid Build Coastguard Worker return false;
561*8975f5c5SAndroid Build Coastguard Worker }
562*8975f5c5SAndroid Build Coastguard Worker }
563*8975f5c5SAndroid Build Coastguard Worker
564*8975f5c5SAndroid Build Coastguard Worker // GLES1 texture parameters are a small subset of the others
IsValidGLES1TextureParameter(GLenum pname)565*8975f5c5SAndroid Build Coastguard Worker bool IsValidGLES1TextureParameter(GLenum pname)
566*8975f5c5SAndroid Build Coastguard Worker {
567*8975f5c5SAndroid Build Coastguard Worker switch (pname)
568*8975f5c5SAndroid Build Coastguard Worker {
569*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAG_FILTER:
570*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_FILTER:
571*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_S:
572*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_T:
573*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
574*8975f5c5SAndroid Build Coastguard Worker case GL_GENERATE_MIPMAP:
575*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CROP_RECT_OES:
576*8975f5c5SAndroid Build Coastguard Worker return true;
577*8975f5c5SAndroid Build Coastguard Worker default:
578*8975f5c5SAndroid Build Coastguard Worker return false;
579*8975f5c5SAndroid Build Coastguard Worker }
580*8975f5c5SAndroid Build Coastguard Worker }
581*8975f5c5SAndroid Build Coastguard Worker
GetSamplerParameterCount(GLenum pname)582*8975f5c5SAndroid Build Coastguard Worker unsigned int GetSamplerParameterCount(GLenum pname)
583*8975f5c5SAndroid Build Coastguard Worker {
584*8975f5c5SAndroid Build Coastguard Worker return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
585*8975f5c5SAndroid Build Coastguard Worker }
586*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramDrawAdvancedBlendState(const Context * context,const ProgramExecutable & executable)587*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramDrawAdvancedBlendState(const Context *context,
588*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &executable)
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
591*8975f5c5SAndroid Build Coastguard Worker const BlendEquationBitSet &supportedBlendEquations = executable.getAdvancedBlendEquations();
592*8975f5c5SAndroid Build Coastguard Worker const DrawBufferMask &enabledDrawBufferMask = state.getBlendStateExt().getEnabledMask();
593*8975f5c5SAndroid Build Coastguard Worker
594*8975f5c5SAndroid Build Coastguard Worker // Zero (default) means everything is BlendEquationType::Add, so check can be skipped
595*8975f5c5SAndroid Build Coastguard Worker if (state.getBlendStateExt().getEquationColorBits() != 0)
596*8975f5c5SAndroid Build Coastguard Worker {
597*8975f5c5SAndroid Build Coastguard Worker for (size_t blendEnabledBufferIndex : enabledDrawBufferMask)
598*8975f5c5SAndroid Build Coastguard Worker {
599*8975f5c5SAndroid Build Coastguard Worker const gl::BlendEquationType enabledBlendEquation =
600*8975f5c5SAndroid Build Coastguard Worker state.getBlendStateExt().getEquationColorIndexed(blendEnabledBufferIndex);
601*8975f5c5SAndroid Build Coastguard Worker
602*8975f5c5SAndroid Build Coastguard Worker if (enabledBlendEquation < gl::BlendEquationType::Multiply ||
603*8975f5c5SAndroid Build Coastguard Worker enabledBlendEquation > gl::BlendEquationType::HslLuminosity)
604*8975f5c5SAndroid Build Coastguard Worker {
605*8975f5c5SAndroid Build Coastguard Worker continue;
606*8975f5c5SAndroid Build Coastguard Worker }
607*8975f5c5SAndroid Build Coastguard Worker
608*8975f5c5SAndroid Build Coastguard Worker if (!supportedBlendEquations.test(enabledBlendEquation))
609*8975f5c5SAndroid Build Coastguard Worker {
610*8975f5c5SAndroid Build Coastguard Worker return gl::err::kBlendEquationNotEnabled;
611*8975f5c5SAndroid Build Coastguard Worker }
612*8975f5c5SAndroid Build Coastguard Worker }
613*8975f5c5SAndroid Build Coastguard Worker }
614*8975f5c5SAndroid Build Coastguard Worker
615*8975f5c5SAndroid Build Coastguard Worker return nullptr;
616*8975f5c5SAndroid Build Coastguard Worker }
617*8975f5c5SAndroid Build Coastguard Worker
ShPixelLocalStorageFormatToGLenum(ShPixelLocalStorageFormat format)618*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE GLenum ShPixelLocalStorageFormatToGLenum(ShPixelLocalStorageFormat format)
619*8975f5c5SAndroid Build Coastguard Worker {
620*8975f5c5SAndroid Build Coastguard Worker switch (format)
621*8975f5c5SAndroid Build Coastguard Worker {
622*8975f5c5SAndroid Build Coastguard Worker case ShPixelLocalStorageFormat::NotPLS:
623*8975f5c5SAndroid Build Coastguard Worker return GL_NONE;
624*8975f5c5SAndroid Build Coastguard Worker case ShPixelLocalStorageFormat::RGBA8:
625*8975f5c5SAndroid Build Coastguard Worker return GL_RGBA8;
626*8975f5c5SAndroid Build Coastguard Worker case ShPixelLocalStorageFormat::RGBA8I:
627*8975f5c5SAndroid Build Coastguard Worker return GL_RGBA8I;
628*8975f5c5SAndroid Build Coastguard Worker case ShPixelLocalStorageFormat::RGBA8UI:
629*8975f5c5SAndroid Build Coastguard Worker return GL_RGBA8UI;
630*8975f5c5SAndroid Build Coastguard Worker case ShPixelLocalStorageFormat::R32UI:
631*8975f5c5SAndroid Build Coastguard Worker return GL_R32UI;
632*8975f5c5SAndroid Build Coastguard Worker case ShPixelLocalStorageFormat::R32F:
633*8975f5c5SAndroid Build Coastguard Worker return GL_R32F;
634*8975f5c5SAndroid Build Coastguard Worker }
635*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
636*8975f5c5SAndroid Build Coastguard Worker return GL_NONE;
637*8975f5c5SAndroid Build Coastguard Worker }
638*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramDrawStates(const Context * context,const Extensions & extensions,const ProgramExecutable & executable)639*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE const char *ValidateProgramDrawStates(const Context *context,
640*8975f5c5SAndroid Build Coastguard Worker const Extensions &extensions,
641*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &executable)
642*8975f5c5SAndroid Build Coastguard Worker {
643*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
644*8975f5c5SAndroid Build Coastguard Worker if (extensions.multiviewOVR || extensions.multiview2OVR)
645*8975f5c5SAndroid Build Coastguard Worker {
646*8975f5c5SAndroid Build Coastguard Worker const int programNumViews = executable.usesMultiview() ? executable.getNumViews() : 1;
647*8975f5c5SAndroid Build Coastguard Worker Framebuffer *framebuffer = state.getDrawFramebuffer();
648*8975f5c5SAndroid Build Coastguard Worker const int framebufferNumViews = framebuffer->getNumViews();
649*8975f5c5SAndroid Build Coastguard Worker
650*8975f5c5SAndroid Build Coastguard Worker if (framebufferNumViews != programNumViews)
651*8975f5c5SAndroid Build Coastguard Worker {
652*8975f5c5SAndroid Build Coastguard Worker return gl::err::kMultiviewMismatch;
653*8975f5c5SAndroid Build Coastguard Worker }
654*8975f5c5SAndroid Build Coastguard Worker
655*8975f5c5SAndroid Build Coastguard Worker if (state.isTransformFeedbackActiveUnpaused() && framebufferNumViews > 1)
656*8975f5c5SAndroid Build Coastguard Worker {
657*8975f5c5SAndroid Build Coastguard Worker return gl::err::kMultiviewTransformFeedback;
658*8975f5c5SAndroid Build Coastguard Worker }
659*8975f5c5SAndroid Build Coastguard Worker
660*8975f5c5SAndroid Build Coastguard Worker if (extensions.disjointTimerQueryEXT && framebufferNumViews > 1 &&
661*8975f5c5SAndroid Build Coastguard Worker state.isQueryActive(QueryType::TimeElapsed))
662*8975f5c5SAndroid Build Coastguard Worker {
663*8975f5c5SAndroid Build Coastguard Worker return gl::err::kMultiviewTimerQuery;
664*8975f5c5SAndroid Build Coastguard Worker }
665*8975f5c5SAndroid Build Coastguard Worker }
666*8975f5c5SAndroid Build Coastguard Worker
667*8975f5c5SAndroid Build Coastguard Worker // Uniform buffer validation
668*8975f5c5SAndroid Build Coastguard Worker for (size_t uniformBlockIndex = 0; uniformBlockIndex < executable.getUniformBlocks().size();
669*8975f5c5SAndroid Build Coastguard Worker uniformBlockIndex++)
670*8975f5c5SAndroid Build Coastguard Worker {
671*8975f5c5SAndroid Build Coastguard Worker const InterfaceBlock &uniformBlock = executable.getUniformBlockByIndex(uniformBlockIndex);
672*8975f5c5SAndroid Build Coastguard Worker GLuint blockBinding = executable.getUniformBlockBinding(uniformBlockIndex);
673*8975f5c5SAndroid Build Coastguard Worker const OffsetBindingPointer<Buffer> &uniformBuffer =
674*8975f5c5SAndroid Build Coastguard Worker state.getIndexedUniformBuffer(blockBinding);
675*8975f5c5SAndroid Build Coastguard Worker
676*8975f5c5SAndroid Build Coastguard Worker if (uniformBuffer.get() == nullptr && context->isWebGL())
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker // undefined behaviour
679*8975f5c5SAndroid Build Coastguard Worker return gl::err::kUniformBufferUnbound;
680*8975f5c5SAndroid Build Coastguard Worker }
681*8975f5c5SAndroid Build Coastguard Worker
682*8975f5c5SAndroid Build Coastguard Worker size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
683*8975f5c5SAndroid Build Coastguard Worker if (uniformBufferSize < uniformBlock.pod.dataSize &&
684*8975f5c5SAndroid Build Coastguard Worker (context->isWebGL() || context->isBufferAccessValidationEnabled()))
685*8975f5c5SAndroid Build Coastguard Worker {
686*8975f5c5SAndroid Build Coastguard Worker // undefined behaviour
687*8975f5c5SAndroid Build Coastguard Worker return gl::err::kUniformBufferTooSmall;
688*8975f5c5SAndroid Build Coastguard Worker }
689*8975f5c5SAndroid Build Coastguard Worker
690*8975f5c5SAndroid Build Coastguard Worker if (uniformBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
691*8975f5c5SAndroid Build Coastguard Worker {
692*8975f5c5SAndroid Build Coastguard Worker return gl::err::kUniformBufferBoundForTransformFeedback;
693*8975f5c5SAndroid Build Coastguard Worker }
694*8975f5c5SAndroid Build Coastguard Worker }
695*8975f5c5SAndroid Build Coastguard Worker
696*8975f5c5SAndroid Build Coastguard Worker // ANGLE_shader_pixel_local_storage validation.
697*8975f5c5SAndroid Build Coastguard Worker if (extensions.shaderPixelLocalStorageANGLE)
698*8975f5c5SAndroid Build Coastguard Worker {
699*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = state.getDrawFramebuffer();
700*8975f5c5SAndroid Build Coastguard Worker const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
701*8975f5c5SAndroid Build Coastguard Worker const auto &shaderPLSFormats = executable.getPixelLocalStorageFormats();
702*8975f5c5SAndroid Build Coastguard Worker size_t activePLSCount = context->getState().getPixelLocalStorageActivePlanes();
703*8975f5c5SAndroid Build Coastguard Worker
704*8975f5c5SAndroid Build Coastguard Worker if (shaderPLSFormats.size() > activePLSCount)
705*8975f5c5SAndroid Build Coastguard Worker {
706*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if a draw is issued with a fragment shader that has a
707*8975f5c5SAndroid Build Coastguard Worker // pixel local uniform bound to an inactive pixel local storage plane.
708*8975f5c5SAndroid Build Coastguard Worker return gl::err::kPLSDrawProgramPlanesInactive;
709*8975f5c5SAndroid Build Coastguard Worker }
710*8975f5c5SAndroid Build Coastguard Worker
711*8975f5c5SAndroid Build Coastguard Worker if (shaderPLSFormats.size() < activePLSCount)
712*8975f5c5SAndroid Build Coastguard Worker {
713*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if a draw is issued with a fragment shader that does
714*8975f5c5SAndroid Build Coastguard Worker // _not_ have a pixel local uniform bound to an _active_ pixel local storage plane
715*8975f5c5SAndroid Build Coastguard Worker // (i.e., the fragment shader must declare uniforms bound to every single active pixel
716*8975f5c5SAndroid Build Coastguard Worker // local storage plane).
717*8975f5c5SAndroid Build Coastguard Worker return gl::err::kPLSDrawProgramActivePlanesUnused;
718*8975f5c5SAndroid Build Coastguard Worker }
719*8975f5c5SAndroid Build Coastguard Worker
720*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < activePLSCount; ++i)
721*8975f5c5SAndroid Build Coastguard Worker {
722*8975f5c5SAndroid Build Coastguard Worker const auto &plsPlane = pls->getPlane(static_cast<GLint>(i));
723*8975f5c5SAndroid Build Coastguard Worker ASSERT(plsPlane.isActive());
724*8975f5c5SAndroid Build Coastguard Worker if (shaderPLSFormats[i] == ShPixelLocalStorageFormat::NotPLS)
725*8975f5c5SAndroid Build Coastguard Worker {
726*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if a draw is issued with a fragment shader that
727*8975f5c5SAndroid Build Coastguard Worker // does _not_ have a pixel local uniform bound to an _active_ pixel local storage
728*8975f5c5SAndroid Build Coastguard Worker // plane (i.e., the fragment shader must declare uniforms bound to every single
729*8975f5c5SAndroid Build Coastguard Worker // active pixel local storage plane).
730*8975f5c5SAndroid Build Coastguard Worker return gl::err::kPLSDrawProgramActivePlanesUnused;
731*8975f5c5SAndroid Build Coastguard Worker }
732*8975f5c5SAndroid Build Coastguard Worker
733*8975f5c5SAndroid Build Coastguard Worker if (ShPixelLocalStorageFormatToGLenum(shaderPLSFormats[i]) !=
734*8975f5c5SAndroid Build Coastguard Worker plsPlane.getInternalformat())
735*8975f5c5SAndroid Build Coastguard Worker {
736*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if a draw is issued with a fragment shader that
737*8975f5c5SAndroid Build Coastguard Worker // has a pixel local storage uniform whose format layout qualifier does not
738*8975f5c5SAndroid Build Coastguard Worker // identically match the internalformat of its associated pixel local storage plane
739*8975f5c5SAndroid Build Coastguard Worker // on the current draw framebuffer, as enumerated in Table X.3.
740*8975f5c5SAndroid Build Coastguard Worker return gl::err::kPLSDrawProgramFormatMismatch;
741*8975f5c5SAndroid Build Coastguard Worker }
742*8975f5c5SAndroid Build Coastguard Worker }
743*8975f5c5SAndroid Build Coastguard Worker }
744*8975f5c5SAndroid Build Coastguard Worker
745*8975f5c5SAndroid Build Coastguard Worker // Enabled blend equation validation
746*8975f5c5SAndroid Build Coastguard Worker const char *errorString = nullptr;
747*8975f5c5SAndroid Build Coastguard Worker
748*8975f5c5SAndroid Build Coastguard Worker if (extensions.blendEquationAdvancedKHR)
749*8975f5c5SAndroid Build Coastguard Worker {
750*8975f5c5SAndroid Build Coastguard Worker errorString = ValidateProgramDrawAdvancedBlendState(context, executable);
751*8975f5c5SAndroid Build Coastguard Worker }
752*8975f5c5SAndroid Build Coastguard Worker
753*8975f5c5SAndroid Build Coastguard Worker return errorString;
754*8975f5c5SAndroid Build Coastguard Worker }
755*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
756*8975f5c5SAndroid Build Coastguard Worker
SetRobustLengthParam(const GLsizei * length,GLsizei value)757*8975f5c5SAndroid Build Coastguard Worker void SetRobustLengthParam(const GLsizei *length, GLsizei value)
758*8975f5c5SAndroid Build Coastguard Worker {
759*8975f5c5SAndroid Build Coastguard Worker if (length)
760*8975f5c5SAndroid Build Coastguard Worker {
761*8975f5c5SAndroid Build Coastguard Worker // Currently we modify robust length parameters in the validation layer. We should be only
762*8975f5c5SAndroid Build Coastguard Worker // doing this in the Context instead.
763*8975f5c5SAndroid Build Coastguard Worker // TODO(http://anglebug.com/42263032): Remove when possible.
764*8975f5c5SAndroid Build Coastguard Worker *const_cast<GLsizei *>(length) = value;
765*8975f5c5SAndroid Build Coastguard Worker }
766*8975f5c5SAndroid Build Coastguard Worker }
767*8975f5c5SAndroid Build Coastguard Worker
ValidTextureTarget(const Context * context,TextureType type)768*8975f5c5SAndroid Build Coastguard Worker bool ValidTextureTarget(const Context *context, TextureType type)
769*8975f5c5SAndroid Build Coastguard Worker {
770*8975f5c5SAndroid Build Coastguard Worker switch (type)
771*8975f5c5SAndroid Build Coastguard Worker {
772*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2D:
773*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMap:
774*8975f5c5SAndroid Build Coastguard Worker return true;
775*8975f5c5SAndroid Build Coastguard Worker
776*8975f5c5SAndroid Build Coastguard Worker case TextureType::Rectangle:
777*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().textureRectangleANGLE;
778*8975f5c5SAndroid Build Coastguard Worker
779*8975f5c5SAndroid Build Coastguard Worker case TextureType::_3D:
780*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0 || context->getExtensions().texture3DOES;
781*8975f5c5SAndroid Build Coastguard Worker
782*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DArray:
783*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0;
784*8975f5c5SAndroid Build Coastguard Worker
785*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisample:
786*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_1 ||
787*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureMultisampleANGLE;
788*8975f5c5SAndroid Build Coastguard Worker
789*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisampleArray:
790*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
791*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureStorageMultisample2dArrayOES;
792*8975f5c5SAndroid Build Coastguard Worker
793*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMapArray:
794*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
795*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureCubeMapArrayAny();
796*8975f5c5SAndroid Build Coastguard Worker
797*8975f5c5SAndroid Build Coastguard Worker case TextureType::VideoImage:
798*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().videoTextureWEBGL;
799*8975f5c5SAndroid Build Coastguard Worker
800*8975f5c5SAndroid Build Coastguard Worker case TextureType::Buffer:
801*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
802*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureBufferAny();
803*8975f5c5SAndroid Build Coastguard Worker
804*8975f5c5SAndroid Build Coastguard Worker default:
805*8975f5c5SAndroid Build Coastguard Worker return false;
806*8975f5c5SAndroid Build Coastguard Worker }
807*8975f5c5SAndroid Build Coastguard Worker }
808*8975f5c5SAndroid Build Coastguard Worker
ValidTexture2DTarget(const Context * context,TextureType type)809*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture2DTarget(const Context *context, TextureType type)
810*8975f5c5SAndroid Build Coastguard Worker {
811*8975f5c5SAndroid Build Coastguard Worker switch (type)
812*8975f5c5SAndroid Build Coastguard Worker {
813*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2D:
814*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMap:
815*8975f5c5SAndroid Build Coastguard Worker return true;
816*8975f5c5SAndroid Build Coastguard Worker
817*8975f5c5SAndroid Build Coastguard Worker case TextureType::Rectangle:
818*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().textureRectangleANGLE;
819*8975f5c5SAndroid Build Coastguard Worker
820*8975f5c5SAndroid Build Coastguard Worker default:
821*8975f5c5SAndroid Build Coastguard Worker return false;
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker }
824*8975f5c5SAndroid Build Coastguard Worker
ValidTexture3DTarget(const Context * context,TextureType target)825*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture3DTarget(const Context *context, TextureType target)
826*8975f5c5SAndroid Build Coastguard Worker {
827*8975f5c5SAndroid Build Coastguard Worker switch (target)
828*8975f5c5SAndroid Build Coastguard Worker {
829*8975f5c5SAndroid Build Coastguard Worker case TextureType::_3D:
830*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DArray:
831*8975f5c5SAndroid Build Coastguard Worker return (context->getClientMajorVersion() >= 3);
832*8975f5c5SAndroid Build Coastguard Worker
833*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMapArray:
834*8975f5c5SAndroid Build Coastguard Worker return (context->getClientVersion() >= Version(3, 2) ||
835*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureCubeMapArrayAny());
836*8975f5c5SAndroid Build Coastguard Worker
837*8975f5c5SAndroid Build Coastguard Worker default:
838*8975f5c5SAndroid Build Coastguard Worker return false;
839*8975f5c5SAndroid Build Coastguard Worker }
840*8975f5c5SAndroid Build Coastguard Worker }
841*8975f5c5SAndroid Build Coastguard Worker
842*8975f5c5SAndroid Build Coastguard Worker // Most texture GL calls are not compatible with external textures, so we have a separate validation
843*8975f5c5SAndroid Build Coastguard Worker // function for use in the GL calls that do
ValidTextureExternalTarget(const Context * context,TextureType target)844*8975f5c5SAndroid Build Coastguard Worker bool ValidTextureExternalTarget(const Context *context, TextureType target)
845*8975f5c5SAndroid Build Coastguard Worker {
846*8975f5c5SAndroid Build Coastguard Worker return (target == TextureType::External) &&
847*8975f5c5SAndroid Build Coastguard Worker (context->getExtensions().EGLImageExternalOES ||
848*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().EGLStreamConsumerExternalNV);
849*8975f5c5SAndroid Build Coastguard Worker }
850*8975f5c5SAndroid Build Coastguard Worker
ValidTextureExternalTarget(const Context * context,TextureTarget target)851*8975f5c5SAndroid Build Coastguard Worker bool ValidTextureExternalTarget(const Context *context, TextureTarget target)
852*8975f5c5SAndroid Build Coastguard Worker {
853*8975f5c5SAndroid Build Coastguard Worker return (target == TextureTarget::External) &&
854*8975f5c5SAndroid Build Coastguard Worker ValidTextureExternalTarget(context, TextureType::External);
855*8975f5c5SAndroid Build Coastguard Worker }
856*8975f5c5SAndroid Build Coastguard Worker
857*8975f5c5SAndroid Build Coastguard Worker // This function differs from ValidTextureTarget in that the target must be
858*8975f5c5SAndroid Build Coastguard Worker // usable as the destination of a 2D operation-- so a cube face is valid, but
859*8975f5c5SAndroid Build Coastguard Worker // GL_TEXTURE_CUBE_MAP is not.
860*8975f5c5SAndroid Build Coastguard Worker // Note: duplicate of IsInternalTextureTarget
ValidTexture2DDestinationTarget(const Context * context,TextureTarget target)861*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
862*8975f5c5SAndroid Build Coastguard Worker {
863*8975f5c5SAndroid Build Coastguard Worker switch (target)
864*8975f5c5SAndroid Build Coastguard Worker {
865*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::_2D:
866*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapNegativeX:
867*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapNegativeY:
868*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapNegativeZ:
869*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapPositiveX:
870*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapPositiveY:
871*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapPositiveZ:
872*8975f5c5SAndroid Build Coastguard Worker return true;
873*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::Rectangle:
874*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().textureRectangleANGLE;
875*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::VideoImage:
876*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().videoTextureWEBGL;
877*8975f5c5SAndroid Build Coastguard Worker default:
878*8975f5c5SAndroid Build Coastguard Worker return false;
879*8975f5c5SAndroid Build Coastguard Worker }
880*8975f5c5SAndroid Build Coastguard Worker }
881*8975f5c5SAndroid Build Coastguard Worker
ValidateTransformFeedbackPrimitiveMode(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode transformFeedbackPrimitiveMode,PrimitiveMode renderPrimitiveMode)882*8975f5c5SAndroid Build Coastguard Worker bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
883*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
884*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode transformFeedbackPrimitiveMode,
885*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode renderPrimitiveMode)
886*8975f5c5SAndroid Build Coastguard Worker {
887*8975f5c5SAndroid Build Coastguard Worker ASSERT(context);
888*8975f5c5SAndroid Build Coastguard Worker
889*8975f5c5SAndroid Build Coastguard Worker if ((!context->getExtensions().geometryShaderAny() ||
890*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().tessellationShaderAny()) &&
891*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
892*8975f5c5SAndroid Build Coastguard Worker {
893*8975f5c5SAndroid Build Coastguard Worker // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
894*8975f5c5SAndroid Build Coastguard Worker // that does not match the current transform feedback object's draw mode (if transform
895*8975f5c5SAndroid Build Coastguard Worker // feedback is active), (3.0.2, section 2.14, pg 86)
896*8975f5c5SAndroid Build Coastguard Worker return transformFeedbackPrimitiveMode == renderPrimitiveMode;
897*8975f5c5SAndroid Build Coastguard Worker }
898*8975f5c5SAndroid Build Coastguard Worker
899*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
900*8975f5c5SAndroid Build Coastguard Worker ASSERT(executable);
901*8975f5c5SAndroid Build Coastguard Worker if (executable->hasLinkedShaderStage(ShaderType::Geometry))
902*8975f5c5SAndroid Build Coastguard Worker {
903*8975f5c5SAndroid Build Coastguard Worker // If geometry shader is active, transform feedback mode must match what is output from this
904*8975f5c5SAndroid Build Coastguard Worker // stage.
905*8975f5c5SAndroid Build Coastguard Worker renderPrimitiveMode = executable->getGeometryShaderOutputPrimitiveType();
906*8975f5c5SAndroid Build Coastguard Worker }
907*8975f5c5SAndroid Build Coastguard Worker else if (executable->hasLinkedShaderStage(ShaderType::TessEvaluation))
908*8975f5c5SAndroid Build Coastguard Worker {
909*8975f5c5SAndroid Build Coastguard Worker // Similarly with tessellation shaders, but only if no geometry shader is present. With
910*8975f5c5SAndroid Build Coastguard Worker // tessellation shaders, only triangles are possibly output.
911*8975f5c5SAndroid Build Coastguard Worker return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles &&
912*8975f5c5SAndroid Build Coastguard Worker executable->getTessGenMode() == GL_TRIANGLES;
913*8975f5c5SAndroid Build Coastguard Worker }
914*8975f5c5SAndroid Build Coastguard Worker
915*8975f5c5SAndroid Build Coastguard Worker // [GL_EXT_geometry_shader] Table 12.1gs
916*8975f5c5SAndroid Build Coastguard Worker switch (renderPrimitiveMode)
917*8975f5c5SAndroid Build Coastguard Worker {
918*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Points:
919*8975f5c5SAndroid Build Coastguard Worker return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
920*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Lines:
921*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineStrip:
922*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineLoop:
923*8975f5c5SAndroid Build Coastguard Worker return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
924*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Triangles:
925*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleFan:
926*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleStrip:
927*8975f5c5SAndroid Build Coastguard Worker return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
928*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Patches:
929*8975f5c5SAndroid Build Coastguard Worker return transformFeedbackPrimitiveMode == PrimitiveMode::Patches;
930*8975f5c5SAndroid Build Coastguard Worker default:
931*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
932*8975f5c5SAndroid Build Coastguard Worker return false;
933*8975f5c5SAndroid Build Coastguard Worker }
934*8975f5c5SAndroid Build Coastguard Worker }
935*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawElementsInstancedBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount,GLuint baseinstance)936*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawElementsInstancedBase(const Context *context,
937*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
938*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode mode,
939*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
940*8975f5c5SAndroid Build Coastguard Worker DrawElementsType type,
941*8975f5c5SAndroid Build Coastguard Worker const void *indices,
942*8975f5c5SAndroid Build Coastguard Worker GLsizei primcount,
943*8975f5c5SAndroid Build Coastguard Worker GLuint baseinstance)
944*8975f5c5SAndroid Build Coastguard Worker {
945*8975f5c5SAndroid Build Coastguard Worker if (primcount <= 0)
946*8975f5c5SAndroid Build Coastguard Worker {
947*8975f5c5SAndroid Build Coastguard Worker if (primcount < 0)
948*8975f5c5SAndroid Build Coastguard Worker {
949*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativePrimcount);
950*8975f5c5SAndroid Build Coastguard Worker return false;
951*8975f5c5SAndroid Build Coastguard Worker }
952*8975f5c5SAndroid Build Coastguard Worker
953*8975f5c5SAndroid Build Coastguard Worker // Early exit.
954*8975f5c5SAndroid Build Coastguard Worker return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices,
955*8975f5c5SAndroid Build Coastguard Worker primcount);
956*8975f5c5SAndroid Build Coastguard Worker }
957*8975f5c5SAndroid Build Coastguard Worker
958*8975f5c5SAndroid Build Coastguard Worker if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, primcount))
959*8975f5c5SAndroid Build Coastguard Worker {
960*8975f5c5SAndroid Build Coastguard Worker return false;
961*8975f5c5SAndroid Build Coastguard Worker }
962*8975f5c5SAndroid Build Coastguard Worker
963*8975f5c5SAndroid Build Coastguard Worker if (count == 0)
964*8975f5c5SAndroid Build Coastguard Worker {
965*8975f5c5SAndroid Build Coastguard Worker // Early exit.
966*8975f5c5SAndroid Build Coastguard Worker return true;
967*8975f5c5SAndroid Build Coastguard Worker }
968*8975f5c5SAndroid Build Coastguard Worker
969*8975f5c5SAndroid Build Coastguard Worker return ValidateDrawInstancedAttribs(context, entryPoint, primcount, baseinstance);
970*8975f5c5SAndroid Build Coastguard Worker }
971*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawArraysInstancedBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount,GLuint baseinstance)972*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawArraysInstancedBase(const Context *context,
973*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
974*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode mode,
975*8975f5c5SAndroid Build Coastguard Worker GLint first,
976*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
977*8975f5c5SAndroid Build Coastguard Worker GLsizei primcount,
978*8975f5c5SAndroid Build Coastguard Worker GLuint baseinstance)
979*8975f5c5SAndroid Build Coastguard Worker {
980*8975f5c5SAndroid Build Coastguard Worker if (primcount <= 0)
981*8975f5c5SAndroid Build Coastguard Worker {
982*8975f5c5SAndroid Build Coastguard Worker if (primcount < 0)
983*8975f5c5SAndroid Build Coastguard Worker {
984*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativePrimcount);
985*8975f5c5SAndroid Build Coastguard Worker return false;
986*8975f5c5SAndroid Build Coastguard Worker }
987*8975f5c5SAndroid Build Coastguard Worker
988*8975f5c5SAndroid Build Coastguard Worker // Early exit.
989*8975f5c5SAndroid Build Coastguard Worker return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount);
990*8975f5c5SAndroid Build Coastguard Worker }
991*8975f5c5SAndroid Build Coastguard Worker
992*8975f5c5SAndroid Build Coastguard Worker if (!ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount))
993*8975f5c5SAndroid Build Coastguard Worker {
994*8975f5c5SAndroid Build Coastguard Worker return false;
995*8975f5c5SAndroid Build Coastguard Worker }
996*8975f5c5SAndroid Build Coastguard Worker
997*8975f5c5SAndroid Build Coastguard Worker if (count == 0)
998*8975f5c5SAndroid Build Coastguard Worker {
999*8975f5c5SAndroid Build Coastguard Worker // Early exit.
1000*8975f5c5SAndroid Build Coastguard Worker return true;
1001*8975f5c5SAndroid Build Coastguard Worker }
1002*8975f5c5SAndroid Build Coastguard Worker
1003*8975f5c5SAndroid Build Coastguard Worker return ValidateDrawInstancedAttribs(context, entryPoint, primcount, baseinstance);
1004*8975f5c5SAndroid Build Coastguard Worker }
1005*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawInstancedANGLE(const Context * context,angle::EntryPoint entryPoint)1006*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint)
1007*8975f5c5SAndroid Build Coastguard Worker {
1008*8975f5c5SAndroid Build Coastguard Worker // Verify there is at least one active attribute with a divisor of zero
1009*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
1010*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = state.getLinkedProgramExecutable(context);
1011*8975f5c5SAndroid Build Coastguard Worker
1012*8975f5c5SAndroid Build Coastguard Worker if (!executable)
1013*8975f5c5SAndroid Build Coastguard Worker {
1014*8975f5c5SAndroid Build Coastguard Worker // No executable means there is no Program/PPO bound, which is undefined behavior, but isn't
1015*8975f5c5SAndroid Build Coastguard Worker // an error.
1016*8975f5c5SAndroid Build Coastguard Worker context->getState().getDebug().insertMessage(
1017*8975f5c5SAndroid Build Coastguard Worker GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, 0, GL_DEBUG_SEVERITY_HIGH,
1018*8975f5c5SAndroid Build Coastguard Worker std::string("Attempting to draw without a program"), gl::LOG_WARN, entryPoint);
1019*8975f5c5SAndroid Build Coastguard Worker return true;
1020*8975f5c5SAndroid Build Coastguard Worker }
1021*8975f5c5SAndroid Build Coastguard Worker
1022*8975f5c5SAndroid Build Coastguard Worker const auto &attribs = state.getVertexArray()->getVertexAttributes();
1023*8975f5c5SAndroid Build Coastguard Worker const auto &bindings = state.getVertexArray()->getVertexBindings();
1024*8975f5c5SAndroid Build Coastguard Worker for (size_t attributeIndex = 0; attributeIndex < attribs.size(); attributeIndex++)
1025*8975f5c5SAndroid Build Coastguard Worker {
1026*8975f5c5SAndroid Build Coastguard Worker const VertexAttribute &attrib = attribs[attributeIndex];
1027*8975f5c5SAndroid Build Coastguard Worker const VertexBinding &binding = bindings[attrib.bindingIndex];
1028*8975f5c5SAndroid Build Coastguard Worker if (executable->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
1029*8975f5c5SAndroid Build Coastguard Worker {
1030*8975f5c5SAndroid Build Coastguard Worker return true;
1031*8975f5c5SAndroid Build Coastguard Worker }
1032*8975f5c5SAndroid Build Coastguard Worker }
1033*8975f5c5SAndroid Build Coastguard Worker
1034*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoZeroDivisor);
1035*8975f5c5SAndroid Build Coastguard Worker return false;
1036*8975f5c5SAndroid Build Coastguard Worker }
1037*8975f5c5SAndroid Build Coastguard Worker
ValidTexture3DDestinationTarget(const Context * context,TextureTarget target)1038*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target)
1039*8975f5c5SAndroid Build Coastguard Worker {
1040*8975f5c5SAndroid Build Coastguard Worker switch (target)
1041*8975f5c5SAndroid Build Coastguard Worker {
1042*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::_3D:
1043*8975f5c5SAndroid Build Coastguard Worker return true;
1044*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::_2DArray:
1045*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= Version(3, 0);
1046*8975f5c5SAndroid Build Coastguard Worker case TextureTarget::CubeMapArray:
1047*8975f5c5SAndroid Build Coastguard Worker return (context->getClientVersion() >= Version(3, 2) ||
1048*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureCubeMapArrayAny());
1049*8975f5c5SAndroid Build Coastguard Worker default:
1050*8975f5c5SAndroid Build Coastguard Worker return false;
1051*8975f5c5SAndroid Build Coastguard Worker }
1052*8975f5c5SAndroid Build Coastguard Worker }
1053*8975f5c5SAndroid Build Coastguard Worker
ValidTexLevelDestinationTarget(const Context * context,TextureType type)1054*8975f5c5SAndroid Build Coastguard Worker bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
1055*8975f5c5SAndroid Build Coastguard Worker {
1056*8975f5c5SAndroid Build Coastguard Worker switch (type)
1057*8975f5c5SAndroid Build Coastguard Worker {
1058*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2D:
1059*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMap:
1060*8975f5c5SAndroid Build Coastguard Worker return true;
1061*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DArray:
1062*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0;
1063*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisample:
1064*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_1 ||
1065*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureMultisampleANGLE;
1066*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisampleArray:
1067*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
1068*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureStorageMultisample2dArrayOES;
1069*8975f5c5SAndroid Build Coastguard Worker case TextureType::_3D:
1070*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_0 || context->getExtensions().texture3DOES;
1071*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMapArray:
1072*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
1073*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureCubeMapArrayAny();
1074*8975f5c5SAndroid Build Coastguard Worker case TextureType::Rectangle:
1075*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().textureRectangleANGLE;
1076*8975f5c5SAndroid Build Coastguard Worker case TextureType::Buffer:
1077*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
1078*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureBufferAny();
1079*8975f5c5SAndroid Build Coastguard Worker default:
1080*8975f5c5SAndroid Build Coastguard Worker return false;
1081*8975f5c5SAndroid Build Coastguard Worker }
1082*8975f5c5SAndroid Build Coastguard Worker }
1083*8975f5c5SAndroid Build Coastguard Worker
ValidFramebufferTarget(const Context * context,GLenum target)1084*8975f5c5SAndroid Build Coastguard Worker bool ValidFramebufferTarget(const Context *context, GLenum target)
1085*8975f5c5SAndroid Build Coastguard Worker {
1086*8975f5c5SAndroid Build Coastguard Worker static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
1087*8975f5c5SAndroid Build Coastguard Worker GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
1088*8975f5c5SAndroid Build Coastguard Worker "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
1089*8975f5c5SAndroid Build Coastguard Worker
1090*8975f5c5SAndroid Build Coastguard Worker switch (target)
1091*8975f5c5SAndroid Build Coastguard Worker {
1092*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER:
1093*8975f5c5SAndroid Build Coastguard Worker return true;
1094*8975f5c5SAndroid Build Coastguard Worker
1095*8975f5c5SAndroid Build Coastguard Worker case GL_READ_FRAMEBUFFER:
1096*8975f5c5SAndroid Build Coastguard Worker case GL_DRAW_FRAMEBUFFER:
1097*8975f5c5SAndroid Build Coastguard Worker return (context->getExtensions().framebufferBlitAny() ||
1098*8975f5c5SAndroid Build Coastguard Worker context->getClientMajorVersion() >= 3);
1099*8975f5c5SAndroid Build Coastguard Worker
1100*8975f5c5SAndroid Build Coastguard Worker default:
1101*8975f5c5SAndroid Build Coastguard Worker return false;
1102*8975f5c5SAndroid Build Coastguard Worker }
1103*8975f5c5SAndroid Build Coastguard Worker }
1104*8975f5c5SAndroid Build Coastguard Worker
ValidMipLevel(const Context * context,TextureType type,GLint level)1105*8975f5c5SAndroid Build Coastguard Worker bool ValidMipLevel(const Context *context, TextureType type, GLint level)
1106*8975f5c5SAndroid Build Coastguard Worker {
1107*8975f5c5SAndroid Build Coastguard Worker const auto &caps = context->getCaps();
1108*8975f5c5SAndroid Build Coastguard Worker int maxDimension = 0;
1109*8975f5c5SAndroid Build Coastguard Worker switch (type)
1110*8975f5c5SAndroid Build Coastguard Worker {
1111*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2D:
1112*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DArray:
1113*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.max2DTextureSize;
1114*8975f5c5SAndroid Build Coastguard Worker break;
1115*8975f5c5SAndroid Build Coastguard Worker
1116*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMap:
1117*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMapArray:
1118*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.maxCubeMapTextureSize;
1119*8975f5c5SAndroid Build Coastguard Worker break;
1120*8975f5c5SAndroid Build Coastguard Worker
1121*8975f5c5SAndroid Build Coastguard Worker case TextureType::External:
1122*8975f5c5SAndroid Build Coastguard Worker case TextureType::Rectangle:
1123*8975f5c5SAndroid Build Coastguard Worker case TextureType::VideoImage:
1124*8975f5c5SAndroid Build Coastguard Worker case TextureType::Buffer:
1125*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisample:
1126*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DMultisampleArray:
1127*8975f5c5SAndroid Build Coastguard Worker return level == 0;
1128*8975f5c5SAndroid Build Coastguard Worker
1129*8975f5c5SAndroid Build Coastguard Worker case TextureType::_3D:
1130*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.max3DTextureSize;
1131*8975f5c5SAndroid Build Coastguard Worker break;
1132*8975f5c5SAndroid Build Coastguard Worker
1133*8975f5c5SAndroid Build Coastguard Worker default:
1134*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1135*8975f5c5SAndroid Build Coastguard Worker }
1136*8975f5c5SAndroid Build Coastguard Worker
1137*8975f5c5SAndroid Build Coastguard Worker return level <= log2(maxDimension) && level >= 0;
1138*8975f5c5SAndroid Build Coastguard Worker }
1139*8975f5c5SAndroid Build Coastguard Worker
ValidImageSizeParameters(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLint level,GLsizei width,GLsizei height,GLsizei depth,bool isSubImage)1140*8975f5c5SAndroid Build Coastguard Worker bool ValidImageSizeParameters(const Context *context,
1141*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1142*8975f5c5SAndroid Build Coastguard Worker TextureType target,
1143*8975f5c5SAndroid Build Coastguard Worker GLint level,
1144*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
1145*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
1146*8975f5c5SAndroid Build Coastguard Worker GLsizei depth,
1147*8975f5c5SAndroid Build Coastguard Worker bool isSubImage)
1148*8975f5c5SAndroid Build Coastguard Worker {
1149*8975f5c5SAndroid Build Coastguard Worker if (width < 0 || height < 0 || depth < 0)
1150*8975f5c5SAndroid Build Coastguard Worker {
1151*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
1152*8975f5c5SAndroid Build Coastguard Worker return false;
1153*8975f5c5SAndroid Build Coastguard Worker }
1154*8975f5c5SAndroid Build Coastguard Worker // TexSubImage parameters can be NPOT without textureNPOT extension,
1155*8975f5c5SAndroid Build Coastguard Worker // as long as the destination texture is POT.
1156*8975f5c5SAndroid Build Coastguard Worker bool hasNPOTSupport =
1157*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureNpotOES || context->getClientVersion() >= Version(3, 0);
1158*8975f5c5SAndroid Build Coastguard Worker if (!isSubImage && !hasNPOTSupport &&
1159*8975f5c5SAndroid Build Coastguard Worker (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
1160*8975f5c5SAndroid Build Coastguard Worker {
1161*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureNotPow2);
1162*8975f5c5SAndroid Build Coastguard Worker return false;
1163*8975f5c5SAndroid Build Coastguard Worker }
1164*8975f5c5SAndroid Build Coastguard Worker
1165*8975f5c5SAndroid Build Coastguard Worker if (!ValidMipLevel(context, target, level))
1166*8975f5c5SAndroid Build Coastguard Worker {
1167*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
1168*8975f5c5SAndroid Build Coastguard Worker return false;
1169*8975f5c5SAndroid Build Coastguard Worker }
1170*8975f5c5SAndroid Build Coastguard Worker
1171*8975f5c5SAndroid Build Coastguard Worker return true;
1172*8975f5c5SAndroid Build Coastguard Worker }
1173*8975f5c5SAndroid Build Coastguard Worker
ValidCompressedBaseLevel(GLsizei size,GLuint blockSize,GLint level)1174*8975f5c5SAndroid Build Coastguard Worker bool ValidCompressedBaseLevel(GLsizei size, GLuint blockSize, GLint level)
1175*8975f5c5SAndroid Build Coastguard Worker {
1176*8975f5c5SAndroid Build Coastguard Worker // Already checked in ValidMipLevel.
1177*8975f5c5SAndroid Build Coastguard Worker ASSERT(level < 32);
1178*8975f5c5SAndroid Build Coastguard Worker // This function is used only for 4x4 BC formats.
1179*8975f5c5SAndroid Build Coastguard Worker ASSERT(blockSize == 4);
1180*8975f5c5SAndroid Build Coastguard Worker // Use the constant value to avoid division.
1181*8975f5c5SAndroid Build Coastguard Worker return ((size << level) % 4) == 0;
1182*8975f5c5SAndroid Build Coastguard Worker }
1183*8975f5c5SAndroid Build Coastguard Worker
ValidCompressedImageSize(const Context * context,GLenum internalFormat,GLint level,GLsizei width,GLsizei height,GLsizei depth)1184*8975f5c5SAndroid Build Coastguard Worker bool ValidCompressedImageSize(const Context *context,
1185*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1186*8975f5c5SAndroid Build Coastguard Worker GLint level,
1187*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
1188*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
1189*8975f5c5SAndroid Build Coastguard Worker GLsizei depth)
1190*8975f5c5SAndroid Build Coastguard Worker {
1191*8975f5c5SAndroid Build Coastguard Worker if (width < 0 || height < 0)
1192*8975f5c5SAndroid Build Coastguard Worker {
1193*8975f5c5SAndroid Build Coastguard Worker return false;
1194*8975f5c5SAndroid Build Coastguard Worker }
1195*8975f5c5SAndroid Build Coastguard Worker
1196*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
1197*8975f5c5SAndroid Build Coastguard Worker
1198*8975f5c5SAndroid Build Coastguard Worker if (!formatInfo.compressed && !formatInfo.paletted)
1199*8975f5c5SAndroid Build Coastguard Worker {
1200*8975f5c5SAndroid Build Coastguard Worker return false;
1201*8975f5c5SAndroid Build Coastguard Worker }
1202*8975f5c5SAndroid Build Coastguard Worker
1203*8975f5c5SAndroid Build Coastguard Worker // A texture format can not be both block-compressed and paletted
1204*8975f5c5SAndroid Build Coastguard Worker ASSERT(!(formatInfo.compressed && formatInfo.paletted));
1205*8975f5c5SAndroid Build Coastguard Worker
1206*8975f5c5SAndroid Build Coastguard Worker if (formatInfo.compressed)
1207*8975f5c5SAndroid Build Coastguard Worker {
1208*8975f5c5SAndroid Build Coastguard Worker // Only PVRTC1 requires dimensions to be powers of two
1209*8975f5c5SAndroid Build Coastguard Worker if (IsPVRTC1Format(internalFormat))
1210*8975f5c5SAndroid Build Coastguard Worker {
1211*8975f5c5SAndroid Build Coastguard Worker if (!isPow2(width) || !isPow2(height))
1212*8975f5c5SAndroid Build Coastguard Worker {
1213*8975f5c5SAndroid Build Coastguard Worker return false;
1214*8975f5c5SAndroid Build Coastguard Worker }
1215*8975f5c5SAndroid Build Coastguard Worker
1216*8975f5c5SAndroid Build Coastguard Worker if (context->getLimitations().squarePvrtc1)
1217*8975f5c5SAndroid Build Coastguard Worker {
1218*8975f5c5SAndroid Build Coastguard Worker if (width != height)
1219*8975f5c5SAndroid Build Coastguard Worker {
1220*8975f5c5SAndroid Build Coastguard Worker return false;
1221*8975f5c5SAndroid Build Coastguard Worker }
1222*8975f5c5SAndroid Build Coastguard Worker }
1223*8975f5c5SAndroid Build Coastguard Worker }
1224*8975f5c5SAndroid Build Coastguard Worker
1225*8975f5c5SAndroid Build Coastguard Worker if (CompressedTextureFormatRequiresExactSize(internalFormat))
1226*8975f5c5SAndroid Build Coastguard Worker {
1227*8975f5c5SAndroid Build Coastguard Worker // In WebGL compatibility mode and D3D, enforce that the base level implied
1228*8975f5c5SAndroid Build Coastguard Worker // by the compressed texture's mip level would conform to the block
1229*8975f5c5SAndroid Build Coastguard Worker // size.
1230*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL() ||
1231*8975f5c5SAndroid Build Coastguard Worker context->getLimitations().compressedBaseMipLevelMultipleOfFour)
1232*8975f5c5SAndroid Build Coastguard Worker {
1233*8975f5c5SAndroid Build Coastguard Worker // This check is performed only for BC formats.
1234*8975f5c5SAndroid Build Coastguard Worker ASSERT(formatInfo.compressedBlockDepth == 1);
1235*8975f5c5SAndroid Build Coastguard Worker if (!ValidCompressedBaseLevel(width, formatInfo.compressedBlockWidth, level) ||
1236*8975f5c5SAndroid Build Coastguard Worker !ValidCompressedBaseLevel(height, formatInfo.compressedBlockHeight, level))
1237*8975f5c5SAndroid Build Coastguard Worker {
1238*8975f5c5SAndroid Build Coastguard Worker return false;
1239*8975f5c5SAndroid Build Coastguard Worker }
1240*8975f5c5SAndroid Build Coastguard Worker }
1241*8975f5c5SAndroid Build Coastguard Worker // non-WebGL and non-D3D check is not necessary for the following formats
1242*8975f5c5SAndroid Build Coastguard Worker // From EXT_texture_compression_s3tc specification:
1243*8975f5c5SAndroid Build Coastguard Worker // If the width or height is not a multiple of four, there will be 4x4 blocks at the
1244*8975f5c5SAndroid Build Coastguard Worker // edge of the image that contain "extra" texels that are not part of the image. From
1245*8975f5c5SAndroid Build Coastguard Worker // EXT_texture_compression_bptc & EXT_texture_compression_rgtc specification: If an
1246*8975f5c5SAndroid Build Coastguard Worker // RGTC/BPTC image has a width or height that is not a multiple of four, the data
1247*8975f5c5SAndroid Build Coastguard Worker // corresponding to texels outside the image are irrelevant and undefined.
1248*8975f5c5SAndroid Build Coastguard Worker }
1249*8975f5c5SAndroid Build Coastguard Worker }
1250*8975f5c5SAndroid Build Coastguard Worker
1251*8975f5c5SAndroid Build Coastguard Worker if (formatInfo.paletted)
1252*8975f5c5SAndroid Build Coastguard Worker {
1253*8975f5c5SAndroid Build Coastguard Worker // TODO(http://anglebug.com/42266155): multi-level paletted images
1254*8975f5c5SAndroid Build Coastguard Worker if (level != 0)
1255*8975f5c5SAndroid Build Coastguard Worker {
1256*8975f5c5SAndroid Build Coastguard Worker return false;
1257*8975f5c5SAndroid Build Coastguard Worker }
1258*8975f5c5SAndroid Build Coastguard Worker
1259*8975f5c5SAndroid Build Coastguard Worker if (!isPow2(width) || !isPow2(height))
1260*8975f5c5SAndroid Build Coastguard Worker {
1261*8975f5c5SAndroid Build Coastguard Worker return false;
1262*8975f5c5SAndroid Build Coastguard Worker }
1263*8975f5c5SAndroid Build Coastguard Worker }
1264*8975f5c5SAndroid Build Coastguard Worker
1265*8975f5c5SAndroid Build Coastguard Worker return true;
1266*8975f5c5SAndroid Build Coastguard Worker }
1267*8975f5c5SAndroid Build Coastguard Worker
ValidCompressedSubImageSize(const Context * context,GLenum internalFormat,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,size_t textureWidth,size_t textureHeight,size_t textureDepth)1268*8975f5c5SAndroid Build Coastguard Worker bool ValidCompressedSubImageSize(const Context *context,
1269*8975f5c5SAndroid Build Coastguard Worker GLenum internalFormat,
1270*8975f5c5SAndroid Build Coastguard Worker GLint xoffset,
1271*8975f5c5SAndroid Build Coastguard Worker GLint yoffset,
1272*8975f5c5SAndroid Build Coastguard Worker GLint zoffset,
1273*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
1274*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
1275*8975f5c5SAndroid Build Coastguard Worker GLsizei depth,
1276*8975f5c5SAndroid Build Coastguard Worker size_t textureWidth,
1277*8975f5c5SAndroid Build Coastguard Worker size_t textureHeight,
1278*8975f5c5SAndroid Build Coastguard Worker size_t textureDepth)
1279*8975f5c5SAndroid Build Coastguard Worker {
1280*8975f5c5SAndroid Build Coastguard Worker // Passing non-compressed internal format to sub-image compressed entry points generates
1281*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION, so check it here.
1282*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
1283*8975f5c5SAndroid Build Coastguard Worker if (!formatInfo.compressed)
1284*8975f5c5SAndroid Build Coastguard Worker {
1285*8975f5c5SAndroid Build Coastguard Worker return false;
1286*8975f5c5SAndroid Build Coastguard Worker }
1287*8975f5c5SAndroid Build Coastguard Worker
1288*8975f5c5SAndroid Build Coastguard Worker // Negative dimensions already checked in ValidImageSizeParameters called by
1289*8975f5c5SAndroid Build Coastguard Worker // ValidateES2TexImageParametersBase or ValidateES3TexImageParametersBase.
1290*8975f5c5SAndroid Build Coastguard Worker ASSERT(width >= 0 && height >= 0 && depth >= 0);
1291*8975f5c5SAndroid Build Coastguard Worker
1292*8975f5c5SAndroid Build Coastguard Worker // Negative and overflowed offsets already checked in ValidateES2TexImageParametersBase or
1293*8975f5c5SAndroid Build Coastguard Worker // ValidateES3TexImageParametersBase.
1294*8975f5c5SAndroid Build Coastguard Worker ASSERT(xoffset >= 0 && yoffset >= 0 && zoffset >= 0);
1295*8975f5c5SAndroid Build Coastguard Worker ASSERT(std::numeric_limits<GLsizei>::max() - xoffset >= width &&
1296*8975f5c5SAndroid Build Coastguard Worker std::numeric_limits<GLsizei>::max() - yoffset >= height &&
1297*8975f5c5SAndroid Build Coastguard Worker std::numeric_limits<GLsizei>::max() - zoffset >= depth);
1298*8975f5c5SAndroid Build Coastguard Worker
1299*8975f5c5SAndroid Build Coastguard Worker // Ensure that format's block dimensions are set.
1300*8975f5c5SAndroid Build Coastguard Worker ASSERT(formatInfo.compressedBlockWidth > 0 && formatInfo.compressedBlockHeight > 0 &&
1301*8975f5c5SAndroid Build Coastguard Worker formatInfo.compressedBlockDepth > 0);
1302*8975f5c5SAndroid Build Coastguard Worker
1303*8975f5c5SAndroid Build Coastguard Worker // Check if the whole image is being replaced. For 2D texture blocks, zoffset and depth do not
1304*8975f5c5SAndroid Build Coastguard Worker // affect whether the replaced region fills the entire image.
1305*8975f5c5SAndroid Build Coastguard Worker if ((xoffset == 0 && static_cast<size_t>(width) == textureWidth) &&
1306*8975f5c5SAndroid Build Coastguard Worker (yoffset == 0 && static_cast<size_t>(height) == textureHeight) &&
1307*8975f5c5SAndroid Build Coastguard Worker ((zoffset == 0 && static_cast<size_t>(depth) == textureDepth) ||
1308*8975f5c5SAndroid Build Coastguard Worker formatInfo.compressedBlockDepth == 1))
1309*8975f5c5SAndroid Build Coastguard Worker {
1310*8975f5c5SAndroid Build Coastguard Worker // All compressed formats support whole image replacement, early pass.
1311*8975f5c5SAndroid Build Coastguard Worker return true;
1312*8975f5c5SAndroid Build Coastguard Worker }
1313*8975f5c5SAndroid Build Coastguard Worker
1314*8975f5c5SAndroid Build Coastguard Worker // The replaced region does not match the image size. Fail if the format does not support
1315*8975f5c5SAndroid Build Coastguard Worker // partial updates.
1316*8975f5c5SAndroid Build Coastguard Worker if (CompressedFormatRequiresWholeImage(internalFormat))
1317*8975f5c5SAndroid Build Coastguard Worker {
1318*8975f5c5SAndroid Build Coastguard Worker return false;
1319*8975f5c5SAndroid Build Coastguard Worker }
1320*8975f5c5SAndroid Build Coastguard Worker
1321*8975f5c5SAndroid Build Coastguard Worker // The format supports partial updates. Check that the origin of the replaced region is aligned
1322*8975f5c5SAndroid Build Coastguard Worker // to block boundaries.
1323*8975f5c5SAndroid Build Coastguard Worker if (xoffset % formatInfo.compressedBlockWidth != 0 ||
1324*8975f5c5SAndroid Build Coastguard Worker yoffset % formatInfo.compressedBlockHeight != 0 ||
1325*8975f5c5SAndroid Build Coastguard Worker zoffset % formatInfo.compressedBlockDepth != 0)
1326*8975f5c5SAndroid Build Coastguard Worker {
1327*8975f5c5SAndroid Build Coastguard Worker return false;
1328*8975f5c5SAndroid Build Coastguard Worker }
1329*8975f5c5SAndroid Build Coastguard Worker
1330*8975f5c5SAndroid Build Coastguard Worker // The replaced region dimensions must either be multiples of the block dimensions or exactly
1331*8975f5c5SAndroid Build Coastguard Worker // reach the image boundaries.
1332*8975f5c5SAndroid Build Coastguard Worker return (static_cast<size_t>(xoffset + width) == textureWidth ||
1333*8975f5c5SAndroid Build Coastguard Worker width % formatInfo.compressedBlockWidth == 0) &&
1334*8975f5c5SAndroid Build Coastguard Worker (static_cast<size_t>(yoffset + height) == textureHeight ||
1335*8975f5c5SAndroid Build Coastguard Worker height % formatInfo.compressedBlockHeight == 0) &&
1336*8975f5c5SAndroid Build Coastguard Worker (static_cast<size_t>(zoffset + depth) == textureDepth ||
1337*8975f5c5SAndroid Build Coastguard Worker depth % formatInfo.compressedBlockDepth == 0);
1338*8975f5c5SAndroid Build Coastguard Worker }
1339*8975f5c5SAndroid Build Coastguard Worker
ValidImageDataSize(const Context * context,angle::EntryPoint entryPoint,TextureType texType,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels,GLsizei imageSize)1340*8975f5c5SAndroid Build Coastguard Worker bool ValidImageDataSize(const Context *context,
1341*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1342*8975f5c5SAndroid Build Coastguard Worker TextureType texType,
1343*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
1344*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
1345*8975f5c5SAndroid Build Coastguard Worker GLsizei depth,
1346*8975f5c5SAndroid Build Coastguard Worker GLenum format,
1347*8975f5c5SAndroid Build Coastguard Worker GLenum type,
1348*8975f5c5SAndroid Build Coastguard Worker const void *pixels,
1349*8975f5c5SAndroid Build Coastguard Worker GLsizei imageSize)
1350*8975f5c5SAndroid Build Coastguard Worker {
1351*8975f5c5SAndroid Build Coastguard Worker Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
1352*8975f5c5SAndroid Build Coastguard Worker if (pixelUnpackBuffer == nullptr && imageSize < 0)
1353*8975f5c5SAndroid Build Coastguard Worker {
1354*8975f5c5SAndroid Build Coastguard Worker // Checks are not required
1355*8975f5c5SAndroid Build Coastguard Worker return true;
1356*8975f5c5SAndroid Build Coastguard Worker }
1357*8975f5c5SAndroid Build Coastguard Worker
1358*8975f5c5SAndroid Build Coastguard Worker // ...the data would be unpacked from the buffer object such that the memory reads required
1359*8975f5c5SAndroid Build Coastguard Worker // would exceed the data store size.
1360*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
1361*8975f5c5SAndroid Build Coastguard Worker if (formatInfo.internalFormat == GL_NONE)
1362*8975f5c5SAndroid Build Coastguard Worker {
1363*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1364*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalErrorFormatNotFound);
1365*8975f5c5SAndroid Build Coastguard Worker return false;
1366*8975f5c5SAndroid Build Coastguard Worker }
1367*8975f5c5SAndroid Build Coastguard Worker const Extents size(width, height, depth);
1368*8975f5c5SAndroid Build Coastguard Worker const auto &unpack = context->getState().getUnpackState();
1369*8975f5c5SAndroid Build Coastguard Worker
1370*8975f5c5SAndroid Build Coastguard Worker bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
1371*8975f5c5SAndroid Build Coastguard Worker GLuint endByte = 0;
1372*8975f5c5SAndroid Build Coastguard Worker if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
1373*8975f5c5SAndroid Build Coastguard Worker {
1374*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
1375*8975f5c5SAndroid Build Coastguard Worker return false;
1376*8975f5c5SAndroid Build Coastguard Worker }
1377*8975f5c5SAndroid Build Coastguard Worker
1378*8975f5c5SAndroid Build Coastguard Worker if (pixelUnpackBuffer)
1379*8975f5c5SAndroid Build Coastguard Worker {
1380*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<size_t> checkedEndByte(endByte);
1381*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
1382*8975f5c5SAndroid Build Coastguard Worker checkedEndByte += checkedOffset;
1383*8975f5c5SAndroid Build Coastguard Worker
1384*8975f5c5SAndroid Build Coastguard Worker if (!checkedEndByte.IsValid() ||
1385*8975f5c5SAndroid Build Coastguard Worker (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
1386*8975f5c5SAndroid Build Coastguard Worker {
1387*8975f5c5SAndroid Build Coastguard Worker // Overflow past the end of the buffer
1388*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
1389*8975f5c5SAndroid Build Coastguard Worker return false;
1390*8975f5c5SAndroid Build Coastguard Worker }
1391*8975f5c5SAndroid Build Coastguard Worker if (pixelUnpackBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
1392*8975f5c5SAndroid Build Coastguard Worker {
1393*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1394*8975f5c5SAndroid Build Coastguard Worker kPixelUnpackBufferBoundForTransformFeedback);
1395*8975f5c5SAndroid Build Coastguard Worker return false;
1396*8975f5c5SAndroid Build Coastguard Worker }
1397*8975f5c5SAndroid Build Coastguard Worker }
1398*8975f5c5SAndroid Build Coastguard Worker else
1399*8975f5c5SAndroid Build Coastguard Worker {
1400*8975f5c5SAndroid Build Coastguard Worker ASSERT(imageSize >= 0);
1401*8975f5c5SAndroid Build Coastguard Worker if (pixels == nullptr && imageSize != 0)
1402*8975f5c5SAndroid Build Coastguard Worker {
1403*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImageSizeMustBeZero);
1404*8975f5c5SAndroid Build Coastguard Worker return false;
1405*8975f5c5SAndroid Build Coastguard Worker }
1406*8975f5c5SAndroid Build Coastguard Worker
1407*8975f5c5SAndroid Build Coastguard Worker if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
1408*8975f5c5SAndroid Build Coastguard Worker {
1409*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImageSizeTooSmall);
1410*8975f5c5SAndroid Build Coastguard Worker return false;
1411*8975f5c5SAndroid Build Coastguard Worker }
1412*8975f5c5SAndroid Build Coastguard Worker }
1413*8975f5c5SAndroid Build Coastguard Worker
1414*8975f5c5SAndroid Build Coastguard Worker return true;
1415*8975f5c5SAndroid Build Coastguard Worker }
1416*8975f5c5SAndroid Build Coastguard Worker
ValidQueryType(const Context * context,QueryType queryType)1417*8975f5c5SAndroid Build Coastguard Worker bool ValidQueryType(const Context *context, QueryType queryType)
1418*8975f5c5SAndroid Build Coastguard Worker {
1419*8975f5c5SAndroid Build Coastguard Worker switch (queryType)
1420*8975f5c5SAndroid Build Coastguard Worker {
1421*8975f5c5SAndroid Build Coastguard Worker case QueryType::AnySamples:
1422*8975f5c5SAndroid Build Coastguard Worker case QueryType::AnySamplesConservative:
1423*8975f5c5SAndroid Build Coastguard Worker return context->getClientMajorVersion() >= 3 ||
1424*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().occlusionQueryBooleanEXT;
1425*8975f5c5SAndroid Build Coastguard Worker case QueryType::TransformFeedbackPrimitivesWritten:
1426*8975f5c5SAndroid Build Coastguard Worker return (context->getClientMajorVersion() >= 3);
1427*8975f5c5SAndroid Build Coastguard Worker case QueryType::TimeElapsed:
1428*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().disjointTimerQueryEXT;
1429*8975f5c5SAndroid Build Coastguard Worker case QueryType::CommandsCompleted:
1430*8975f5c5SAndroid Build Coastguard Worker return context->getExtensions().syncQueryCHROMIUM;
1431*8975f5c5SAndroid Build Coastguard Worker case QueryType::PrimitivesGenerated:
1432*8975f5c5SAndroid Build Coastguard Worker return context->getClientVersion() >= ES_3_2 ||
1433*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().geometryShaderAny();
1434*8975f5c5SAndroid Build Coastguard Worker default:
1435*8975f5c5SAndroid Build Coastguard Worker return false;
1436*8975f5c5SAndroid Build Coastguard Worker }
1437*8975f5c5SAndroid Build Coastguard Worker }
1438*8975f5c5SAndroid Build Coastguard Worker
ValidateWebGLVertexAttribPointer(const Context * context,angle::EntryPoint entryPoint,VertexAttribType type,GLboolean normalized,GLsizei stride,const void * ptr,bool pureInteger)1439*8975f5c5SAndroid Build Coastguard Worker bool ValidateWebGLVertexAttribPointer(const Context *context,
1440*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1441*8975f5c5SAndroid Build Coastguard Worker VertexAttribType type,
1442*8975f5c5SAndroid Build Coastguard Worker GLboolean normalized,
1443*8975f5c5SAndroid Build Coastguard Worker GLsizei stride,
1444*8975f5c5SAndroid Build Coastguard Worker const void *ptr,
1445*8975f5c5SAndroid Build Coastguard Worker bool pureInteger)
1446*8975f5c5SAndroid Build Coastguard Worker {
1447*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->isWebGL());
1448*8975f5c5SAndroid Build Coastguard Worker // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
1449*8975f5c5SAndroid Build Coastguard Worker // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
1450*8975f5c5SAndroid Build Coastguard Worker // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
1451*8975f5c5SAndroid Build Coastguard Worker // parameter exceeds 255.
1452*8975f5c5SAndroid Build Coastguard Worker constexpr GLsizei kMaxWebGLStride = 255;
1453*8975f5c5SAndroid Build Coastguard Worker if (stride > kMaxWebGLStride)
1454*8975f5c5SAndroid Build Coastguard Worker {
1455*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kStrideExceedsWebGLLimit);
1456*8975f5c5SAndroid Build Coastguard Worker return false;
1457*8975f5c5SAndroid Build Coastguard Worker }
1458*8975f5c5SAndroid Build Coastguard Worker
1459*8975f5c5SAndroid Build Coastguard Worker // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1460*8975f5c5SAndroid Build Coastguard Worker // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1461*8975f5c5SAndroid Build Coastguard Worker // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1462*8975f5c5SAndroid Build Coastguard Worker // or an INVALID_OPERATION error is generated.
1463*8975f5c5SAndroid Build Coastguard Worker angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1464*8975f5c5SAndroid Build Coastguard Worker size_t typeSize = GetVertexFormatSize(internalType);
1465*8975f5c5SAndroid Build Coastguard Worker
1466*8975f5c5SAndroid Build Coastguard Worker ASSERT(isPow2(typeSize) && typeSize > 0);
1467*8975f5c5SAndroid Build Coastguard Worker size_t sizeMask = (typeSize - 1);
1468*8975f5c5SAndroid Build Coastguard Worker if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1469*8975f5c5SAndroid Build Coastguard Worker {
1470*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
1471*8975f5c5SAndroid Build Coastguard Worker return false;
1472*8975f5c5SAndroid Build Coastguard Worker }
1473*8975f5c5SAndroid Build Coastguard Worker
1474*8975f5c5SAndroid Build Coastguard Worker if ((stride & sizeMask) != 0)
1475*8975f5c5SAndroid Build Coastguard Worker {
1476*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
1477*8975f5c5SAndroid Build Coastguard Worker return false;
1478*8975f5c5SAndroid Build Coastguard Worker }
1479*8975f5c5SAndroid Build Coastguard Worker
1480*8975f5c5SAndroid Build Coastguard Worker return true;
1481*8975f5c5SAndroid Build Coastguard Worker }
1482*8975f5c5SAndroid Build Coastguard Worker
GetValidProgramNoResolve(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID id)1483*8975f5c5SAndroid Build Coastguard Worker Program *GetValidProgramNoResolve(const Context *context,
1484*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1485*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID id)
1486*8975f5c5SAndroid Build Coastguard Worker {
1487*8975f5c5SAndroid Build Coastguard Worker // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1488*8975f5c5SAndroid Build Coastguard Worker // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1489*8975f5c5SAndroid Build Coastguard Worker // or program object and INVALID_OPERATION if the provided name identifies an object
1490*8975f5c5SAndroid Build Coastguard Worker // that is not the expected type."
1491*8975f5c5SAndroid Build Coastguard Worker
1492*8975f5c5SAndroid Build Coastguard Worker Program *validProgram = context->getProgramNoResolveLink(id);
1493*8975f5c5SAndroid Build Coastguard Worker
1494*8975f5c5SAndroid Build Coastguard Worker if (!validProgram)
1495*8975f5c5SAndroid Build Coastguard Worker {
1496*8975f5c5SAndroid Build Coastguard Worker if (context->getShaderNoResolveCompile(id))
1497*8975f5c5SAndroid Build Coastguard Worker {
1498*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
1499*8975f5c5SAndroid Build Coastguard Worker }
1500*8975f5c5SAndroid Build Coastguard Worker else
1501*8975f5c5SAndroid Build Coastguard Worker {
1502*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramName);
1503*8975f5c5SAndroid Build Coastguard Worker }
1504*8975f5c5SAndroid Build Coastguard Worker }
1505*8975f5c5SAndroid Build Coastguard Worker
1506*8975f5c5SAndroid Build Coastguard Worker return validProgram;
1507*8975f5c5SAndroid Build Coastguard Worker }
1508*8975f5c5SAndroid Build Coastguard Worker
GetValidProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID id)1509*8975f5c5SAndroid Build Coastguard Worker Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id)
1510*8975f5c5SAndroid Build Coastguard Worker {
1511*8975f5c5SAndroid Build Coastguard Worker Program *program = GetValidProgramNoResolve(context, entryPoint, id);
1512*8975f5c5SAndroid Build Coastguard Worker if (program)
1513*8975f5c5SAndroid Build Coastguard Worker {
1514*8975f5c5SAndroid Build Coastguard Worker program->resolveLink(context);
1515*8975f5c5SAndroid Build Coastguard Worker }
1516*8975f5c5SAndroid Build Coastguard Worker return program;
1517*8975f5c5SAndroid Build Coastguard Worker }
1518*8975f5c5SAndroid Build Coastguard Worker
GetValidShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID id)1519*8975f5c5SAndroid Build Coastguard Worker Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id)
1520*8975f5c5SAndroid Build Coastguard Worker {
1521*8975f5c5SAndroid Build Coastguard Worker // See ValidProgram for spec details.
1522*8975f5c5SAndroid Build Coastguard Worker
1523*8975f5c5SAndroid Build Coastguard Worker Shader *validShader = context->getShaderNoResolveCompile(id);
1524*8975f5c5SAndroid Build Coastguard Worker
1525*8975f5c5SAndroid Build Coastguard Worker if (!validShader)
1526*8975f5c5SAndroid Build Coastguard Worker {
1527*8975f5c5SAndroid Build Coastguard Worker if (context->getProgramNoResolveLink(id))
1528*8975f5c5SAndroid Build Coastguard Worker {
1529*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedShaderName);
1530*8975f5c5SAndroid Build Coastguard Worker }
1531*8975f5c5SAndroid Build Coastguard Worker else
1532*8975f5c5SAndroid Build Coastguard Worker {
1533*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidShaderName);
1534*8975f5c5SAndroid Build Coastguard Worker }
1535*8975f5c5SAndroid Build Coastguard Worker }
1536*8975f5c5SAndroid Build Coastguard Worker
1537*8975f5c5SAndroid Build Coastguard Worker return validShader;
1538*8975f5c5SAndroid Build Coastguard Worker }
1539*8975f5c5SAndroid Build Coastguard Worker
ValidateAttachmentTarget(const Context * context,angle::EntryPoint entryPoint,GLenum attachment)1540*8975f5c5SAndroid Build Coastguard Worker bool ValidateAttachmentTarget(const Context *context,
1541*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1542*8975f5c5SAndroid Build Coastguard Worker GLenum attachment)
1543*8975f5c5SAndroid Build Coastguard Worker {
1544*8975f5c5SAndroid Build Coastguard Worker if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
1545*8975f5c5SAndroid Build Coastguard Worker {
1546*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffersEXT)
1547*8975f5c5SAndroid Build Coastguard Worker {
1548*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
1549*8975f5c5SAndroid Build Coastguard Worker return false;
1550*8975f5c5SAndroid Build Coastguard Worker }
1551*8975f5c5SAndroid Build Coastguard Worker
1552*8975f5c5SAndroid Build Coastguard Worker // Color attachment 0 is validated below because it is always valid
1553*8975f5c5SAndroid Build Coastguard Worker const int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
1554*8975f5c5SAndroid Build Coastguard Worker if (colorAttachment >= context->getCaps().maxColorAttachments)
1555*8975f5c5SAndroid Build Coastguard Worker {
1556*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
1557*8975f5c5SAndroid Build Coastguard Worker return false;
1558*8975f5c5SAndroid Build Coastguard Worker }
1559*8975f5c5SAndroid Build Coastguard Worker }
1560*8975f5c5SAndroid Build Coastguard Worker else
1561*8975f5c5SAndroid Build Coastguard Worker {
1562*8975f5c5SAndroid Build Coastguard Worker switch (attachment)
1563*8975f5c5SAndroid Build Coastguard Worker {
1564*8975f5c5SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT0:
1565*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
1566*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
1567*8975f5c5SAndroid Build Coastguard Worker break;
1568*8975f5c5SAndroid Build Coastguard Worker
1569*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
1570*8975f5c5SAndroid Build Coastguard Worker if (!context->isWebGL() && context->getClientMajorVersion() < 3)
1571*8975f5c5SAndroid Build Coastguard Worker {
1572*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
1573*8975f5c5SAndroid Build Coastguard Worker return false;
1574*8975f5c5SAndroid Build Coastguard Worker }
1575*8975f5c5SAndroid Build Coastguard Worker break;
1576*8975f5c5SAndroid Build Coastguard Worker
1577*8975f5c5SAndroid Build Coastguard Worker default:
1578*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
1579*8975f5c5SAndroid Build Coastguard Worker return false;
1580*8975f5c5SAndroid Build Coastguard Worker }
1581*8975f5c5SAndroid Build Coastguard Worker }
1582*8975f5c5SAndroid Build Coastguard Worker
1583*8975f5c5SAndroid Build Coastguard Worker return true;
1584*8975f5c5SAndroid Build Coastguard Worker }
1585*8975f5c5SAndroid Build Coastguard Worker
ValidateRenderbufferStorageParametersBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)1586*8975f5c5SAndroid Build Coastguard Worker bool ValidateRenderbufferStorageParametersBase(const Context *context,
1587*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1588*8975f5c5SAndroid Build Coastguard Worker GLenum target,
1589*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
1590*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
1591*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
1592*8975f5c5SAndroid Build Coastguard Worker GLsizei height)
1593*8975f5c5SAndroid Build Coastguard Worker {
1594*8975f5c5SAndroid Build Coastguard Worker switch (target)
1595*8975f5c5SAndroid Build Coastguard Worker {
1596*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
1597*8975f5c5SAndroid Build Coastguard Worker break;
1598*8975f5c5SAndroid Build Coastguard Worker default:
1599*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
1600*8975f5c5SAndroid Build Coastguard Worker return false;
1601*8975f5c5SAndroid Build Coastguard Worker }
1602*8975f5c5SAndroid Build Coastguard Worker
1603*8975f5c5SAndroid Build Coastguard Worker if (width < 0 || height < 0 || samples < 0)
1604*8975f5c5SAndroid Build Coastguard Worker {
1605*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
1606*8975f5c5SAndroid Build Coastguard Worker return false;
1607*8975f5c5SAndroid Build Coastguard Worker }
1608*8975f5c5SAndroid Build Coastguard Worker
1609*8975f5c5SAndroid Build Coastguard Worker // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1610*8975f5c5SAndroid Build Coastguard Worker GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1611*8975f5c5SAndroid Build Coastguard Worker
1612*8975f5c5SAndroid Build Coastguard Worker const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
1613*8975f5c5SAndroid Build Coastguard Worker if (!formatCaps.renderbuffer)
1614*8975f5c5SAndroid Build Coastguard Worker {
1615*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
1616*8975f5c5SAndroid Build Coastguard Worker return false;
1617*8975f5c5SAndroid Build Coastguard Worker }
1618*8975f5c5SAndroid Build Coastguard Worker
1619*8975f5c5SAndroid Build Coastguard Worker // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1620*8975f5c5SAndroid Build Coastguard Worker // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
1621*8975f5c5SAndroid Build Coastguard Worker // only sized internal formats.
1622*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
1623*8975f5c5SAndroid Build Coastguard Worker if (formatInfo.internalFormat == GL_NONE)
1624*8975f5c5SAndroid Build Coastguard Worker {
1625*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
1626*8975f5c5SAndroid Build Coastguard Worker return false;
1627*8975f5c5SAndroid Build Coastguard Worker }
1628*8975f5c5SAndroid Build Coastguard Worker
1629*8975f5c5SAndroid Build Coastguard Worker if (std::max(width, height) > context->getCaps().maxRenderbufferSize)
1630*8975f5c5SAndroid Build Coastguard Worker {
1631*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
1632*8975f5c5SAndroid Build Coastguard Worker return false;
1633*8975f5c5SAndroid Build Coastguard Worker }
1634*8975f5c5SAndroid Build Coastguard Worker
1635*8975f5c5SAndroid Build Coastguard Worker RenderbufferID id = context->getState().getRenderbufferId();
1636*8975f5c5SAndroid Build Coastguard Worker if (id.value == 0)
1637*8975f5c5SAndroid Build Coastguard Worker {
1638*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
1639*8975f5c5SAndroid Build Coastguard Worker return false;
1640*8975f5c5SAndroid Build Coastguard Worker }
1641*8975f5c5SAndroid Build Coastguard Worker
1642*8975f5c5SAndroid Build Coastguard Worker return true;
1643*8975f5c5SAndroid Build Coastguard Worker }
1644*8975f5c5SAndroid Build Coastguard Worker
ValidateBlitFramebufferParameters(const Context * context,angle::EntryPoint entryPoint,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)1645*8975f5c5SAndroid Build Coastguard Worker bool ValidateBlitFramebufferParameters(const Context *context,
1646*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1647*8975f5c5SAndroid Build Coastguard Worker GLint srcX0,
1648*8975f5c5SAndroid Build Coastguard Worker GLint srcY0,
1649*8975f5c5SAndroid Build Coastguard Worker GLint srcX1,
1650*8975f5c5SAndroid Build Coastguard Worker GLint srcY1,
1651*8975f5c5SAndroid Build Coastguard Worker GLint dstX0,
1652*8975f5c5SAndroid Build Coastguard Worker GLint dstY0,
1653*8975f5c5SAndroid Build Coastguard Worker GLint dstX1,
1654*8975f5c5SAndroid Build Coastguard Worker GLint dstY1,
1655*8975f5c5SAndroid Build Coastguard Worker GLbitfield mask,
1656*8975f5c5SAndroid Build Coastguard Worker GLenum filter)
1657*8975f5c5SAndroid Build Coastguard Worker {
1658*8975f5c5SAndroid Build Coastguard Worker switch (filter)
1659*8975f5c5SAndroid Build Coastguard Worker {
1660*8975f5c5SAndroid Build Coastguard Worker case GL_NEAREST:
1661*8975f5c5SAndroid Build Coastguard Worker break;
1662*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR:
1663*8975f5c5SAndroid Build Coastguard Worker break;
1664*8975f5c5SAndroid Build Coastguard Worker default:
1665*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kBlitInvalidFilter);
1666*8975f5c5SAndroid Build Coastguard Worker return false;
1667*8975f5c5SAndroid Build Coastguard Worker }
1668*8975f5c5SAndroid Build Coastguard Worker
1669*8975f5c5SAndroid Build Coastguard Worker if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1670*8975f5c5SAndroid Build Coastguard Worker {
1671*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBlitInvalidMask);
1672*8975f5c5SAndroid Build Coastguard Worker return false;
1673*8975f5c5SAndroid Build Coastguard Worker }
1674*8975f5c5SAndroid Build Coastguard Worker
1675*8975f5c5SAndroid Build Coastguard Worker // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1676*8975f5c5SAndroid Build Coastguard Worker // color buffer, leaving only nearest being unfiltered from above
1677*8975f5c5SAndroid Build Coastguard Worker if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1678*8975f5c5SAndroid Build Coastguard Worker {
1679*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
1680*8975f5c5SAndroid Build Coastguard Worker return false;
1681*8975f5c5SAndroid Build Coastguard Worker }
1682*8975f5c5SAndroid Build Coastguard Worker
1683*8975f5c5SAndroid Build Coastguard Worker const auto &glState = context->getState();
1684*8975f5c5SAndroid Build Coastguard Worker Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1685*8975f5c5SAndroid Build Coastguard Worker Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
1686*8975f5c5SAndroid Build Coastguard Worker
1687*8975f5c5SAndroid Build Coastguard Worker if (!readFramebuffer || !drawFramebuffer)
1688*8975f5c5SAndroid Build Coastguard Worker {
1689*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFramebufferMissing);
1690*8975f5c5SAndroid Build Coastguard Worker return false;
1691*8975f5c5SAndroid Build Coastguard Worker }
1692*8975f5c5SAndroid Build Coastguard Worker
1693*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
1694*8975f5c5SAndroid Build Coastguard Worker {
1695*8975f5c5SAndroid Build Coastguard Worker return false;
1696*8975f5c5SAndroid Build Coastguard Worker }
1697*8975f5c5SAndroid Build Coastguard Worker
1698*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFramebufferComplete(context, entryPoint, drawFramebuffer))
1699*8975f5c5SAndroid Build Coastguard Worker {
1700*8975f5c5SAndroid Build Coastguard Worker return false;
1701*8975f5c5SAndroid Build Coastguard Worker }
1702*8975f5c5SAndroid Build Coastguard Worker
1703*8975f5c5SAndroid Build Coastguard Worker // The QCOM_framebuffer_foveated spec:
1704*8975f5c5SAndroid Build Coastguard Worker if (drawFramebuffer->isFoveationEnabled())
1705*8975f5c5SAndroid Build Coastguard Worker {
1706*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated by any API call which causes a framebuffer
1707*8975f5c5SAndroid Build Coastguard Worker // attachment to be written to if the framebuffer attachments have changed for
1708*8975f5c5SAndroid Build Coastguard Worker // a foveated fbo.
1709*8975f5c5SAndroid Build Coastguard Worker if (drawFramebuffer->hasAnyAttachmentChanged())
1710*8975f5c5SAndroid Build Coastguard Worker {
1711*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationAttachmentChanged);
1712*8975f5c5SAndroid Build Coastguard Worker return false;
1713*8975f5c5SAndroid Build Coastguard Worker }
1714*8975f5c5SAndroid Build Coastguard Worker }
1715*8975f5c5SAndroid Build Coastguard Worker
1716*8975f5c5SAndroid Build Coastguard Worker // EXT_YUV_target disallows blitting to or from a YUV framebuffer
1717*8975f5c5SAndroid Build Coastguard Worker if ((mask & GL_COLOR_BUFFER_BIT) != 0 &&
1718*8975f5c5SAndroid Build Coastguard Worker (readFramebuffer->hasYUVAttachment() || drawFramebuffer->hasYUVAttachment()))
1719*8975f5c5SAndroid Build Coastguard Worker {
1720*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitYUVFramebuffer);
1721*8975f5c5SAndroid Build Coastguard Worker return false;
1722*8975f5c5SAndroid Build Coastguard Worker }
1723*8975f5c5SAndroid Build Coastguard Worker
1724*8975f5c5SAndroid Build Coastguard Worker // The draw and read framebuffers can only match if:
1725*8975f5c5SAndroid Build Coastguard Worker // - They are the default framebuffer AND
1726*8975f5c5SAndroid Build Coastguard Worker // - The read/draw surfaces are different
1727*8975f5c5SAndroid Build Coastguard Worker if ((readFramebuffer->id() == drawFramebuffer->id()) &&
1728*8975f5c5SAndroid Build Coastguard Worker ((drawFramebuffer->id() != Framebuffer::kDefaultDrawFramebufferHandle) ||
1729*8975f5c5SAndroid Build Coastguard Worker (context->getCurrentDrawSurface() == context->getCurrentReadSurface())))
1730*8975f5c5SAndroid Build Coastguard Worker {
1731*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitFeedbackLoop);
1732*8975f5c5SAndroid Build Coastguard Worker return false;
1733*8975f5c5SAndroid Build Coastguard Worker }
1734*8975f5c5SAndroid Build Coastguard Worker
1735*8975f5c5SAndroid Build Coastguard Worker // Not allow blitting to MS buffers, therefore if renderToTextureSamples exist,
1736*8975f5c5SAndroid Build Coastguard Worker // consider it MS. checkReadBufferResourceSamples = false
1737*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFramebufferNotMultisampled(context, entryPoint, drawFramebuffer, false))
1738*8975f5c5SAndroid Build Coastguard Worker {
1739*8975f5c5SAndroid Build Coastguard Worker return false;
1740*8975f5c5SAndroid Build Coastguard Worker }
1741*8975f5c5SAndroid Build Coastguard Worker
1742*8975f5c5SAndroid Build Coastguard Worker // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1743*8975f5c5SAndroid Build Coastguard Worker // always run it in order to avoid triggering driver bugs.
1744*8975f5c5SAndroid Build Coastguard Worker if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1745*8975f5c5SAndroid Build Coastguard Worker DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
1746*8975f5c5SAndroid Build Coastguard Worker {
1747*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
1748*8975f5c5SAndroid Build Coastguard Worker return false;
1749*8975f5c5SAndroid Build Coastguard Worker }
1750*8975f5c5SAndroid Build Coastguard Worker
1751*8975f5c5SAndroid Build Coastguard Worker bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1752*8975f5c5SAndroid Build Coastguard Worker
1753*8975f5c5SAndroid Build Coastguard Worker if (mask & GL_COLOR_BUFFER_BIT)
1754*8975f5c5SAndroid Build Coastguard Worker {
1755*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorAttachment();
1756*8975f5c5SAndroid Build Coastguard Worker const Extensions &extensions = context->getExtensions();
1757*8975f5c5SAndroid Build Coastguard Worker
1758*8975f5c5SAndroid Build Coastguard Worker if (readColorBuffer)
1759*8975f5c5SAndroid Build Coastguard Worker {
1760*8975f5c5SAndroid Build Coastguard Worker const Format &readFormat = readColorBuffer->getFormat();
1761*8975f5c5SAndroid Build Coastguard Worker
1762*8975f5c5SAndroid Build Coastguard Worker for (size_t drawbufferIdx = 0;
1763*8975f5c5SAndroid Build Coastguard Worker drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
1764*8975f5c5SAndroid Build Coastguard Worker {
1765*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *attachment =
1766*8975f5c5SAndroid Build Coastguard Worker drawFramebuffer->getDrawBuffer(drawbufferIdx);
1767*8975f5c5SAndroid Build Coastguard Worker if (attachment)
1768*8975f5c5SAndroid Build Coastguard Worker {
1769*8975f5c5SAndroid Build Coastguard Worker const Format &drawFormat = attachment->getFormat();
1770*8975f5c5SAndroid Build Coastguard Worker
1771*8975f5c5SAndroid Build Coastguard Worker // The GL ES 3.0.2 spec (pg 193) states that:
1772*8975f5c5SAndroid Build Coastguard Worker // 1) If the read buffer is fixed point format, the draw buffer must be as well
1773*8975f5c5SAndroid Build Coastguard Worker // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1774*8975f5c5SAndroid Build Coastguard Worker // as well
1775*8975f5c5SAndroid Build Coastguard Worker // 3) If the read buffer is a signed integer format, the draw buffer must be as
1776*8975f5c5SAndroid Build Coastguard Worker // well
1777*8975f5c5SAndroid Build Coastguard Worker // Changes with EXT_color_buffer_float:
1778*8975f5c5SAndroid Build Coastguard Worker // Case 1) is changed to fixed point OR floating point
1779*8975f5c5SAndroid Build Coastguard Worker GLenum readComponentType = readFormat.info->componentType;
1780*8975f5c5SAndroid Build Coastguard Worker GLenum drawComponentType = drawFormat.info->componentType;
1781*8975f5c5SAndroid Build Coastguard Worker bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
1782*8975f5c5SAndroid Build Coastguard Worker readComponentType == GL_SIGNED_NORMALIZED);
1783*8975f5c5SAndroid Build Coastguard Worker bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
1784*8975f5c5SAndroid Build Coastguard Worker drawComponentType == GL_SIGNED_NORMALIZED);
1785*8975f5c5SAndroid Build Coastguard Worker
1786*8975f5c5SAndroid Build Coastguard Worker if (extensions.colorBufferFloatEXT)
1787*8975f5c5SAndroid Build Coastguard Worker {
1788*8975f5c5SAndroid Build Coastguard Worker bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1789*8975f5c5SAndroid Build Coastguard Worker bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1790*8975f5c5SAndroid Build Coastguard Worker
1791*8975f5c5SAndroid Build Coastguard Worker if (readFixedOrFloat != drawFixedOrFloat)
1792*8975f5c5SAndroid Build Coastguard Worker {
1793*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1794*8975f5c5SAndroid Build Coastguard Worker kBlitTypeMismatchFixedOrFloat);
1795*8975f5c5SAndroid Build Coastguard Worker return false;
1796*8975f5c5SAndroid Build Coastguard Worker }
1797*8975f5c5SAndroid Build Coastguard Worker }
1798*8975f5c5SAndroid Build Coastguard Worker else if (readFixedPoint != drawFixedPoint)
1799*8975f5c5SAndroid Build Coastguard Worker {
1800*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitTypeMismatchFixedPoint);
1801*8975f5c5SAndroid Build Coastguard Worker return false;
1802*8975f5c5SAndroid Build Coastguard Worker }
1803*8975f5c5SAndroid Build Coastguard Worker
1804*8975f5c5SAndroid Build Coastguard Worker if (readComponentType == GL_UNSIGNED_INT &&
1805*8975f5c5SAndroid Build Coastguard Worker drawComponentType != GL_UNSIGNED_INT)
1806*8975f5c5SAndroid Build Coastguard Worker {
1807*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1808*8975f5c5SAndroid Build Coastguard Worker kBlitTypeMismatchUnsignedInteger);
1809*8975f5c5SAndroid Build Coastguard Worker return false;
1810*8975f5c5SAndroid Build Coastguard Worker }
1811*8975f5c5SAndroid Build Coastguard Worker
1812*8975f5c5SAndroid Build Coastguard Worker if (readComponentType == GL_INT && drawComponentType != GL_INT)
1813*8975f5c5SAndroid Build Coastguard Worker {
1814*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1815*8975f5c5SAndroid Build Coastguard Worker kBlitTypeMismatchSignedInteger);
1816*8975f5c5SAndroid Build Coastguard Worker return false;
1817*8975f5c5SAndroid Build Coastguard Worker }
1818*8975f5c5SAndroid Build Coastguard Worker
1819*8975f5c5SAndroid Build Coastguard Worker if (readColorBuffer->getResourceSamples() > 0 &&
1820*8975f5c5SAndroid Build Coastguard Worker (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
1821*8975f5c5SAndroid Build Coastguard Worker {
1822*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1823*8975f5c5SAndroid Build Coastguard Worker kBlitMultisampledFormatOrBoundsMismatch);
1824*8975f5c5SAndroid Build Coastguard Worker return false;
1825*8975f5c5SAndroid Build Coastguard Worker }
1826*8975f5c5SAndroid Build Coastguard Worker
1827*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL() && *readColorBuffer == *attachment)
1828*8975f5c5SAndroid Build Coastguard Worker {
1829*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitSameImageColor);
1830*8975f5c5SAndroid Build Coastguard Worker return false;
1831*8975f5c5SAndroid Build Coastguard Worker }
1832*8975f5c5SAndroid Build Coastguard Worker }
1833*8975f5c5SAndroid Build Coastguard Worker }
1834*8975f5c5SAndroid Build Coastguard Worker
1835*8975f5c5SAndroid Build Coastguard Worker if (readFormat.info->isInt() && filter == GL_LINEAR)
1836*8975f5c5SAndroid Build Coastguard Worker {
1837*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitIntegerWithLinearFilter);
1838*8975f5c5SAndroid Build Coastguard Worker return false;
1839*8975f5c5SAndroid Build Coastguard Worker }
1840*8975f5c5SAndroid Build Coastguard Worker }
1841*8975f5c5SAndroid Build Coastguard Worker // In OpenGL ES, blits to/from missing attachments are silently ignored. In WebGL 2.0, this
1842*8975f5c5SAndroid Build Coastguard Worker // is defined to be an error.
1843*8975f5c5SAndroid Build Coastguard Worker else if (context->isWebGL() && drawFramebuffer->hasEnabledDrawBuffer())
1844*8975f5c5SAndroid Build Coastguard Worker {
1845*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitMissingColor);
1846*8975f5c5SAndroid Build Coastguard Worker return false;
1847*8975f5c5SAndroid Build Coastguard Worker }
1848*8975f5c5SAndroid Build Coastguard Worker }
1849*8975f5c5SAndroid Build Coastguard Worker
1850*8975f5c5SAndroid Build Coastguard Worker GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
1851*8975f5c5SAndroid Build Coastguard Worker GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1852*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < 2; i++)
1853*8975f5c5SAndroid Build Coastguard Worker {
1854*8975f5c5SAndroid Build Coastguard Worker if (mask & masks[i])
1855*8975f5c5SAndroid Build Coastguard Worker {
1856*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *readBuffer =
1857*8975f5c5SAndroid Build Coastguard Worker readFramebuffer->getAttachment(context, attachments[i]);
1858*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *drawBuffer =
1859*8975f5c5SAndroid Build Coastguard Worker drawFramebuffer->getAttachment(context, attachments[i]);
1860*8975f5c5SAndroid Build Coastguard Worker
1861*8975f5c5SAndroid Build Coastguard Worker if (readBuffer && drawBuffer)
1862*8975f5c5SAndroid Build Coastguard Worker {
1863*8975f5c5SAndroid Build Coastguard Worker if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
1864*8975f5c5SAndroid Build Coastguard Worker {
1865*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitDepthOrStencilFormatMismatch);
1866*8975f5c5SAndroid Build Coastguard Worker return false;
1867*8975f5c5SAndroid Build Coastguard Worker }
1868*8975f5c5SAndroid Build Coastguard Worker
1869*8975f5c5SAndroid Build Coastguard Worker if (readBuffer->getResourceSamples() > 0 && !sameBounds)
1870*8975f5c5SAndroid Build Coastguard Worker {
1871*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitMultisampledBoundsMismatch);
1872*8975f5c5SAndroid Build Coastguard Worker return false;
1873*8975f5c5SAndroid Build Coastguard Worker }
1874*8975f5c5SAndroid Build Coastguard Worker
1875*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL() && *readBuffer == *drawBuffer)
1876*8975f5c5SAndroid Build Coastguard Worker {
1877*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitSameImageDepthOrStencil);
1878*8975f5c5SAndroid Build Coastguard Worker return false;
1879*8975f5c5SAndroid Build Coastguard Worker }
1880*8975f5c5SAndroid Build Coastguard Worker }
1881*8975f5c5SAndroid Build Coastguard Worker // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1882*8975f5c5SAndroid Build Coastguard Worker else if (context->isWebGL() && drawBuffer)
1883*8975f5c5SAndroid Build Coastguard Worker {
1884*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitMissingDepthOrStencil);
1885*8975f5c5SAndroid Build Coastguard Worker return false;
1886*8975f5c5SAndroid Build Coastguard Worker }
1887*8975f5c5SAndroid Build Coastguard Worker }
1888*8975f5c5SAndroid Build Coastguard Worker }
1889*8975f5c5SAndroid Build Coastguard Worker
1890*8975f5c5SAndroid Build Coastguard Worker // OVR_multiview2:
1891*8975f5c5SAndroid Build Coastguard Worker // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
1892*8975f5c5SAndroid Build Coastguard Worker // current draw framebuffer isMultiview() or the number of
1893*8975f5c5SAndroid Build Coastguard Worker // views in the current read framebuffer is more than one.
1894*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->readDisallowedByMultiview())
1895*8975f5c5SAndroid Build Coastguard Worker {
1896*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
1897*8975f5c5SAndroid Build Coastguard Worker return false;
1898*8975f5c5SAndroid Build Coastguard Worker }
1899*8975f5c5SAndroid Build Coastguard Worker if (drawFramebuffer->isMultiview())
1900*8975f5c5SAndroid Build Coastguard Worker {
1901*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
1902*8975f5c5SAndroid Build Coastguard Worker return false;
1903*8975f5c5SAndroid Build Coastguard Worker }
1904*8975f5c5SAndroid Build Coastguard Worker
1905*8975f5c5SAndroid Build Coastguard Worker return true;
1906*8975f5c5SAndroid Build Coastguard Worker }
1907*8975f5c5SAndroid Build Coastguard Worker
ValidateBindFramebufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,FramebufferID framebuffer)1908*8975f5c5SAndroid Build Coastguard Worker bool ValidateBindFramebufferBase(const Context *context,
1909*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1910*8975f5c5SAndroid Build Coastguard Worker GLenum target,
1911*8975f5c5SAndroid Build Coastguard Worker FramebufferID framebuffer)
1912*8975f5c5SAndroid Build Coastguard Worker {
1913*8975f5c5SAndroid Build Coastguard Worker if (!ValidFramebufferTarget(context, target))
1914*8975f5c5SAndroid Build Coastguard Worker {
1915*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1916*8975f5c5SAndroid Build Coastguard Worker return false;
1917*8975f5c5SAndroid Build Coastguard Worker }
1918*8975f5c5SAndroid Build Coastguard Worker
1919*8975f5c5SAndroid Build Coastguard Worker if (!context->getState().isBindGeneratesResourceEnabled() &&
1920*8975f5c5SAndroid Build Coastguard Worker !context->isFramebufferGenerated(framebuffer))
1921*8975f5c5SAndroid Build Coastguard Worker {
1922*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1923*8975f5c5SAndroid Build Coastguard Worker return false;
1924*8975f5c5SAndroid Build Coastguard Worker }
1925*8975f5c5SAndroid Build Coastguard Worker
1926*8975f5c5SAndroid Build Coastguard Worker return true;
1927*8975f5c5SAndroid Build Coastguard Worker }
1928*8975f5c5SAndroid Build Coastguard Worker
ValidateBindRenderbufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,RenderbufferID renderbuffer)1929*8975f5c5SAndroid Build Coastguard Worker bool ValidateBindRenderbufferBase(const Context *context,
1930*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1931*8975f5c5SAndroid Build Coastguard Worker GLenum target,
1932*8975f5c5SAndroid Build Coastguard Worker RenderbufferID renderbuffer)
1933*8975f5c5SAndroid Build Coastguard Worker {
1934*8975f5c5SAndroid Build Coastguard Worker if (target != GL_RENDERBUFFER)
1935*8975f5c5SAndroid Build Coastguard Worker {
1936*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
1937*8975f5c5SAndroid Build Coastguard Worker return false;
1938*8975f5c5SAndroid Build Coastguard Worker }
1939*8975f5c5SAndroid Build Coastguard Worker
1940*8975f5c5SAndroid Build Coastguard Worker if (!context->getState().isBindGeneratesResourceEnabled() &&
1941*8975f5c5SAndroid Build Coastguard Worker !context->isRenderbufferGenerated(renderbuffer))
1942*8975f5c5SAndroid Build Coastguard Worker {
1943*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1944*8975f5c5SAndroid Build Coastguard Worker return false;
1945*8975f5c5SAndroid Build Coastguard Worker }
1946*8975f5c5SAndroid Build Coastguard Worker
1947*8975f5c5SAndroid Build Coastguard Worker return true;
1948*8975f5c5SAndroid Build Coastguard Worker }
1949*8975f5c5SAndroid Build Coastguard Worker
ValidateFramebufferParameteriBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLint param)1950*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferParameteriBase(const Context *context,
1951*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
1952*8975f5c5SAndroid Build Coastguard Worker GLenum target,
1953*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
1954*8975f5c5SAndroid Build Coastguard Worker GLint param)
1955*8975f5c5SAndroid Build Coastguard Worker {
1956*8975f5c5SAndroid Build Coastguard Worker if (!ValidFramebufferTarget(context, target))
1957*8975f5c5SAndroid Build Coastguard Worker {
1958*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1959*8975f5c5SAndroid Build Coastguard Worker return false;
1960*8975f5c5SAndroid Build Coastguard Worker }
1961*8975f5c5SAndroid Build Coastguard Worker
1962*8975f5c5SAndroid Build Coastguard Worker switch (pname)
1963*8975f5c5SAndroid Build Coastguard Worker {
1964*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1965*8975f5c5SAndroid Build Coastguard Worker {
1966*8975f5c5SAndroid Build Coastguard Worker GLint maxWidth = context->getCaps().maxFramebufferWidth;
1967*8975f5c5SAndroid Build Coastguard Worker if (param < 0 || param > maxWidth)
1968*8975f5c5SAndroid Build Coastguard Worker {
1969*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsFramebufferWidth);
1970*8975f5c5SAndroid Build Coastguard Worker return false;
1971*8975f5c5SAndroid Build Coastguard Worker }
1972*8975f5c5SAndroid Build Coastguard Worker break;
1973*8975f5c5SAndroid Build Coastguard Worker }
1974*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1975*8975f5c5SAndroid Build Coastguard Worker {
1976*8975f5c5SAndroid Build Coastguard Worker GLint maxHeight = context->getCaps().maxFramebufferHeight;
1977*8975f5c5SAndroid Build Coastguard Worker if (param < 0 || param > maxHeight)
1978*8975f5c5SAndroid Build Coastguard Worker {
1979*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsFramebufferHeight);
1980*8975f5c5SAndroid Build Coastguard Worker return false;
1981*8975f5c5SAndroid Build Coastguard Worker }
1982*8975f5c5SAndroid Build Coastguard Worker break;
1983*8975f5c5SAndroid Build Coastguard Worker }
1984*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1985*8975f5c5SAndroid Build Coastguard Worker {
1986*8975f5c5SAndroid Build Coastguard Worker GLint maxSamples = context->getCaps().maxFramebufferSamples;
1987*8975f5c5SAndroid Build Coastguard Worker if (param < 0 || param > maxSamples)
1988*8975f5c5SAndroid Build Coastguard Worker {
1989*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsFramebufferSamples);
1990*8975f5c5SAndroid Build Coastguard Worker return false;
1991*8975f5c5SAndroid Build Coastguard Worker }
1992*8975f5c5SAndroid Build Coastguard Worker break;
1993*8975f5c5SAndroid Build Coastguard Worker }
1994*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1995*8975f5c5SAndroid Build Coastguard Worker {
1996*8975f5c5SAndroid Build Coastguard Worker break;
1997*8975f5c5SAndroid Build Coastguard Worker }
1998*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1999*8975f5c5SAndroid Build Coastguard Worker {
2000*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().geometryShaderAny() &&
2001*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
2002*8975f5c5SAndroid Build Coastguard Worker {
2003*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
2004*8975f5c5SAndroid Build Coastguard Worker return false;
2005*8975f5c5SAndroid Build Coastguard Worker }
2006*8975f5c5SAndroid Build Coastguard Worker GLint maxLayers = context->getCaps().maxFramebufferLayers;
2007*8975f5c5SAndroid Build Coastguard Worker if (param < 0 || param > maxLayers)
2008*8975f5c5SAndroid Build Coastguard Worker {
2009*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferLayer);
2010*8975f5c5SAndroid Build Coastguard Worker return false;
2011*8975f5c5SAndroid Build Coastguard Worker }
2012*8975f5c5SAndroid Build Coastguard Worker break;
2013*8975f5c5SAndroid Build Coastguard Worker }
2014*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_FLIP_Y_MESA:
2015*8975f5c5SAndroid Build Coastguard Worker {
2016*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().framebufferFlipYMESA)
2017*8975f5c5SAndroid Build Coastguard Worker {
2018*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2019*8975f5c5SAndroid Build Coastguard Worker return false;
2020*8975f5c5SAndroid Build Coastguard Worker }
2021*8975f5c5SAndroid Build Coastguard Worker break;
2022*8975f5c5SAndroid Build Coastguard Worker }
2023*8975f5c5SAndroid Build Coastguard Worker default:
2024*8975f5c5SAndroid Build Coastguard Worker {
2025*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2026*8975f5c5SAndroid Build Coastguard Worker return false;
2027*8975f5c5SAndroid Build Coastguard Worker }
2028*8975f5c5SAndroid Build Coastguard Worker }
2029*8975f5c5SAndroid Build Coastguard Worker
2030*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
2031*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
2032*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->isDefault())
2033*8975f5c5SAndroid Build Coastguard Worker {
2034*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebuffer);
2035*8975f5c5SAndroid Build Coastguard Worker return false;
2036*8975f5c5SAndroid Build Coastguard Worker }
2037*8975f5c5SAndroid Build Coastguard Worker return true;
2038*8975f5c5SAndroid Build Coastguard Worker }
2039*8975f5c5SAndroid Build Coastguard Worker
ValidateFramebufferRenderbufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum renderbuffertarget,RenderbufferID renderbuffer)2040*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferRenderbufferBase(const Context *context,
2041*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2042*8975f5c5SAndroid Build Coastguard Worker GLenum target,
2043*8975f5c5SAndroid Build Coastguard Worker GLenum attachment,
2044*8975f5c5SAndroid Build Coastguard Worker GLenum renderbuffertarget,
2045*8975f5c5SAndroid Build Coastguard Worker RenderbufferID renderbuffer)
2046*8975f5c5SAndroid Build Coastguard Worker {
2047*8975f5c5SAndroid Build Coastguard Worker if (!ValidFramebufferTarget(context, target))
2048*8975f5c5SAndroid Build Coastguard Worker {
2049*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
2050*8975f5c5SAndroid Build Coastguard Worker return false;
2051*8975f5c5SAndroid Build Coastguard Worker }
2052*8975f5c5SAndroid Build Coastguard Worker
2053*8975f5c5SAndroid Build Coastguard Worker if (renderbuffertarget != GL_RENDERBUFFER)
2054*8975f5c5SAndroid Build Coastguard Worker {
2055*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
2056*8975f5c5SAndroid Build Coastguard Worker return false;
2057*8975f5c5SAndroid Build Coastguard Worker }
2058*8975f5c5SAndroid Build Coastguard Worker
2059*8975f5c5SAndroid Build Coastguard Worker Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
2060*8975f5c5SAndroid Build Coastguard Worker
2061*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
2062*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->isDefault())
2063*8975f5c5SAndroid Build Coastguard Worker {
2064*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
2065*8975f5c5SAndroid Build Coastguard Worker return false;
2066*8975f5c5SAndroid Build Coastguard Worker }
2067*8975f5c5SAndroid Build Coastguard Worker
2068*8975f5c5SAndroid Build Coastguard Worker if (!ValidateAttachmentTarget(context, entryPoint, attachment))
2069*8975f5c5SAndroid Build Coastguard Worker {
2070*8975f5c5SAndroid Build Coastguard Worker return false;
2071*8975f5c5SAndroid Build Coastguard Worker }
2072*8975f5c5SAndroid Build Coastguard Worker
2073*8975f5c5SAndroid Build Coastguard Worker // [OpenGL ES 2.0.25] Section 4.4.3 page 112
2074*8975f5c5SAndroid Build Coastguard Worker // [OpenGL ES 3.0.2] Section 4.4.2 page 201
2075*8975f5c5SAndroid Build Coastguard Worker // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
2076*8975f5c5SAndroid Build Coastguard Worker // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
2077*8975f5c5SAndroid Build Coastguard Worker if (renderbuffer.value != 0)
2078*8975f5c5SAndroid Build Coastguard Worker {
2079*8975f5c5SAndroid Build Coastguard Worker if (!context->getRenderbuffer(renderbuffer))
2080*8975f5c5SAndroid Build Coastguard Worker {
2081*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
2082*8975f5c5SAndroid Build Coastguard Worker return false;
2083*8975f5c5SAndroid Build Coastguard Worker }
2084*8975f5c5SAndroid Build Coastguard Worker }
2085*8975f5c5SAndroid Build Coastguard Worker
2086*8975f5c5SAndroid Build Coastguard Worker return true;
2087*8975f5c5SAndroid Build Coastguard Worker }
2088*8975f5c5SAndroid Build Coastguard Worker
ValidateFramebufferTextureBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2089*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferTextureBase(const Context *context,
2090*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2091*8975f5c5SAndroid Build Coastguard Worker GLenum target,
2092*8975f5c5SAndroid Build Coastguard Worker GLenum attachment,
2093*8975f5c5SAndroid Build Coastguard Worker TextureID texture,
2094*8975f5c5SAndroid Build Coastguard Worker GLint level)
2095*8975f5c5SAndroid Build Coastguard Worker {
2096*8975f5c5SAndroid Build Coastguard Worker if (!ValidFramebufferTarget(context, target))
2097*8975f5c5SAndroid Build Coastguard Worker {
2098*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
2099*8975f5c5SAndroid Build Coastguard Worker return false;
2100*8975f5c5SAndroid Build Coastguard Worker }
2101*8975f5c5SAndroid Build Coastguard Worker
2102*8975f5c5SAndroid Build Coastguard Worker if (!ValidateAttachmentTarget(context, entryPoint, attachment))
2103*8975f5c5SAndroid Build Coastguard Worker {
2104*8975f5c5SAndroid Build Coastguard Worker return false;
2105*8975f5c5SAndroid Build Coastguard Worker }
2106*8975f5c5SAndroid Build Coastguard Worker
2107*8975f5c5SAndroid Build Coastguard Worker if (texture.value != 0)
2108*8975f5c5SAndroid Build Coastguard Worker {
2109*8975f5c5SAndroid Build Coastguard Worker Texture *tex = context->getTexture(texture);
2110*8975f5c5SAndroid Build Coastguard Worker
2111*8975f5c5SAndroid Build Coastguard Worker if (tex == nullptr)
2112*8975f5c5SAndroid Build Coastguard Worker {
2113*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTexture);
2114*8975f5c5SAndroid Build Coastguard Worker return false;
2115*8975f5c5SAndroid Build Coastguard Worker }
2116*8975f5c5SAndroid Build Coastguard Worker
2117*8975f5c5SAndroid Build Coastguard Worker if (level < 0)
2118*8975f5c5SAndroid Build Coastguard Worker {
2119*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
2120*8975f5c5SAndroid Build Coastguard Worker return false;
2121*8975f5c5SAndroid Build Coastguard Worker }
2122*8975f5c5SAndroid Build Coastguard Worker
2123*8975f5c5SAndroid Build Coastguard Worker // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2124*8975f5c5SAndroid Build Coastguard Worker // An INVALID_VALUE error is generated if texture is not zero and level is
2125*8975f5c5SAndroid Build Coastguard Worker // not a supported texture level for textarget
2126*8975f5c5SAndroid Build Coastguard Worker
2127*8975f5c5SAndroid Build Coastguard Worker // Common criteria for not supported texture levels(other criteria are handled case by case
2128*8975f5c5SAndroid Build Coastguard Worker // in non base functions): If texture refers to an immutable-format texture, level must be
2129*8975f5c5SAndroid Build Coastguard Worker // greater than or equal to zero and smaller than the value of TEXTURE_IMMUTABLE_LEVELS for
2130*8975f5c5SAndroid Build Coastguard Worker // texture.
2131*8975f5c5SAndroid Build Coastguard Worker if (tex->getImmutableFormat() && context->getClientVersion() >= ES_3_1)
2132*8975f5c5SAndroid Build Coastguard Worker {
2133*8975f5c5SAndroid Build Coastguard Worker if (level >= static_cast<GLint>(tex->getImmutableLevels()))
2134*8975f5c5SAndroid Build Coastguard Worker {
2135*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
2136*8975f5c5SAndroid Build Coastguard Worker return false;
2137*8975f5c5SAndroid Build Coastguard Worker }
2138*8975f5c5SAndroid Build Coastguard Worker }
2139*8975f5c5SAndroid Build Coastguard Worker
2140*8975f5c5SAndroid Build Coastguard Worker // GLES spec 3.2, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2141*8975f5c5SAndroid Build Coastguard Worker // An INVALID_OPERATION error is generated if <texture> is the name of a buffer texture.
2142*8975f5c5SAndroid Build Coastguard Worker if ((context->getClientVersion() >= ES_3_2 ||
2143*8975f5c5SAndroid Build Coastguard Worker context->getExtensions().textureBufferAny()) &&
2144*8975f5c5SAndroid Build Coastguard Worker tex->getType() == TextureType::Buffer)
2145*8975f5c5SAndroid Build Coastguard Worker {
2146*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
2147*8975f5c5SAndroid Build Coastguard Worker return false;
2148*8975f5c5SAndroid Build Coastguard Worker }
2149*8975f5c5SAndroid Build Coastguard Worker
2150*8975f5c5SAndroid Build Coastguard Worker if (tex->getState().hasProtectedContent() != context->getState().hasProtectedContent())
2151*8975f5c5SAndroid Build Coastguard Worker {
2152*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2153*8975f5c5SAndroid Build Coastguard Worker "Mismatch between Texture and Context Protected Content state");
2154*8975f5c5SAndroid Build Coastguard Worker return false;
2155*8975f5c5SAndroid Build Coastguard Worker }
2156*8975f5c5SAndroid Build Coastguard Worker }
2157*8975f5c5SAndroid Build Coastguard Worker
2158*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
2159*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
2160*8975f5c5SAndroid Build Coastguard Worker
2161*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->isDefault())
2162*8975f5c5SAndroid Build Coastguard Worker {
2163*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
2164*8975f5c5SAndroid Build Coastguard Worker return false;
2165*8975f5c5SAndroid Build Coastguard Worker }
2166*8975f5c5SAndroid Build Coastguard Worker
2167*8975f5c5SAndroid Build Coastguard Worker return true;
2168*8975f5c5SAndroid Build Coastguard Worker }
2169*8975f5c5SAndroid Build Coastguard Worker
ValidateGenerateMipmapBase(const Context * context,angle::EntryPoint entryPoint,TextureType target)2170*8975f5c5SAndroid Build Coastguard Worker bool ValidateGenerateMipmapBase(const Context *context,
2171*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2172*8975f5c5SAndroid Build Coastguard Worker TextureType target)
2173*8975f5c5SAndroid Build Coastguard Worker {
2174*8975f5c5SAndroid Build Coastguard Worker if (!ValidTextureTarget(context, target))
2175*8975f5c5SAndroid Build Coastguard Worker {
2176*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
2177*8975f5c5SAndroid Build Coastguard Worker return false;
2178*8975f5c5SAndroid Build Coastguard Worker }
2179*8975f5c5SAndroid Build Coastguard Worker
2180*8975f5c5SAndroid Build Coastguard Worker Texture *texture = context->getTextureByType(target);
2181*8975f5c5SAndroid Build Coastguard Worker
2182*8975f5c5SAndroid Build Coastguard Worker if (texture == nullptr)
2183*8975f5c5SAndroid Build Coastguard Worker {
2184*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureNotBound);
2185*8975f5c5SAndroid Build Coastguard Worker return false;
2186*8975f5c5SAndroid Build Coastguard Worker }
2187*8975f5c5SAndroid Build Coastguard Worker
2188*8975f5c5SAndroid Build Coastguard Worker const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
2189*8975f5c5SAndroid Build Coastguard Worker
2190*8975f5c5SAndroid Build Coastguard Worker // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
2191*8975f5c5SAndroid Build Coastguard Worker // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
2192*8975f5c5SAndroid Build Coastguard Worker if (effectiveBaseLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2193*8975f5c5SAndroid Build Coastguard Worker {
2194*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
2195*8975f5c5SAndroid Build Coastguard Worker return false;
2196*8975f5c5SAndroid Build Coastguard Worker }
2197*8975f5c5SAndroid Build Coastguard Worker
2198*8975f5c5SAndroid Build Coastguard Worker TextureTarget baseTarget = (target == TextureType::CubeMap)
2199*8975f5c5SAndroid Build Coastguard Worker ? TextureTarget::CubeMapPositiveX
2200*8975f5c5SAndroid Build Coastguard Worker : NonCubeTextureTypeToTarget(target);
2201*8975f5c5SAndroid Build Coastguard Worker const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
2202*8975f5c5SAndroid Build Coastguard Worker if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
2203*8975f5c5SAndroid Build Coastguard Worker format.stencilBits > 0)
2204*8975f5c5SAndroid Build Coastguard Worker {
2205*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2206*8975f5c5SAndroid Build Coastguard Worker return false;
2207*8975f5c5SAndroid Build Coastguard Worker }
2208*8975f5c5SAndroid Build Coastguard Worker
2209*8975f5c5SAndroid Build Coastguard Worker // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
2210*8975f5c5SAndroid Build Coastguard Worker bool formatUnsized = !format.sized;
2211*8975f5c5SAndroid Build Coastguard Worker bool formatColorRenderableAndFilterable =
2212*8975f5c5SAndroid Build Coastguard Worker format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
2213*8975f5c5SAndroid Build Coastguard Worker format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
2214*8975f5c5SAndroid Build Coastguard Worker if (!formatUnsized && !formatColorRenderableAndFilterable)
2215*8975f5c5SAndroid Build Coastguard Worker {
2216*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2217*8975f5c5SAndroid Build Coastguard Worker return false;
2218*8975f5c5SAndroid Build Coastguard Worker }
2219*8975f5c5SAndroid Build Coastguard Worker
2220*8975f5c5SAndroid Build Coastguard Worker // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
2221*8975f5c5SAndroid Build Coastguard Worker // generation
2222*8975f5c5SAndroid Build Coastguard Worker if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
2223*8975f5c5SAndroid Build Coastguard Worker {
2224*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2225*8975f5c5SAndroid Build Coastguard Worker return false;
2226*8975f5c5SAndroid Build Coastguard Worker }
2227*8975f5c5SAndroid Build Coastguard Worker
2228*8975f5c5SAndroid Build Coastguard Worker // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
2229*8975f5c5SAndroid Build Coastguard Worker // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
2230*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
2231*8975f5c5SAndroid Build Coastguard Worker {
2232*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2233*8975f5c5SAndroid Build Coastguard Worker return false;
2234*8975f5c5SAndroid Build Coastguard Worker }
2235*8975f5c5SAndroid Build Coastguard Worker
2236*8975f5c5SAndroid Build Coastguard Worker // Non-power of 2 ES2 check
2237*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNpotOES &&
2238*8975f5c5SAndroid Build Coastguard Worker (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
2239*8975f5c5SAndroid Build Coastguard Worker !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
2240*8975f5c5SAndroid Build Coastguard Worker {
2241*8975f5c5SAndroid Build Coastguard Worker ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
2242*8975f5c5SAndroid Build Coastguard Worker target == TextureType::CubeMap);
2243*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureNotPow2);
2244*8975f5c5SAndroid Build Coastguard Worker return false;
2245*8975f5c5SAndroid Build Coastguard Worker }
2246*8975f5c5SAndroid Build Coastguard Worker
2247*8975f5c5SAndroid Build Coastguard Worker // Cube completeness check
2248*8975f5c5SAndroid Build Coastguard Worker if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
2249*8975f5c5SAndroid Build Coastguard Worker {
2250*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCubemapIncomplete);
2251*8975f5c5SAndroid Build Coastguard Worker return false;
2252*8975f5c5SAndroid Build Coastguard Worker }
2253*8975f5c5SAndroid Build Coastguard Worker
2254*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL() && (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
2255*8975f5c5SAndroid Build Coastguard Worker texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
2256*8975f5c5SAndroid Build Coastguard Worker {
2257*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
2258*8975f5c5SAndroid Build Coastguard Worker return false;
2259*8975f5c5SAndroid Build Coastguard Worker }
2260*8975f5c5SAndroid Build Coastguard Worker
2261*8975f5c5SAndroid Build Coastguard Worker return true;
2262*8975f5c5SAndroid Build Coastguard Worker }
2263*8975f5c5SAndroid Build Coastguard Worker
ValidateReadPixelsRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const GLsizei * length,const GLsizei * columns,const GLsizei * rows,const void * pixels)2264*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadPixelsRobustANGLE(const Context *context,
2265*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2266*8975f5c5SAndroid Build Coastguard Worker GLint x,
2267*8975f5c5SAndroid Build Coastguard Worker GLint y,
2268*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
2269*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
2270*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2271*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2272*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2273*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2274*8975f5c5SAndroid Build Coastguard Worker const GLsizei *columns,
2275*8975f5c5SAndroid Build Coastguard Worker const GLsizei *rows,
2276*8975f5c5SAndroid Build Coastguard Worker const void *pixels)
2277*8975f5c5SAndroid Build Coastguard Worker {
2278*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2279*8975f5c5SAndroid Build Coastguard Worker {
2280*8975f5c5SAndroid Build Coastguard Worker return false;
2281*8975f5c5SAndroid Build Coastguard Worker }
2282*8975f5c5SAndroid Build Coastguard Worker
2283*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
2284*8975f5c5SAndroid Build Coastguard Worker GLsizei writeColumns = 0;
2285*8975f5c5SAndroid Build Coastguard Worker GLsizei writeRows = 0;
2286*8975f5c5SAndroid Build Coastguard Worker
2287*8975f5c5SAndroid Build Coastguard Worker if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
2288*8975f5c5SAndroid Build Coastguard Worker &writeLength, &writeColumns, &writeRows, pixels))
2289*8975f5c5SAndroid Build Coastguard Worker {
2290*8975f5c5SAndroid Build Coastguard Worker return false;
2291*8975f5c5SAndroid Build Coastguard Worker }
2292*8975f5c5SAndroid Build Coastguard Worker
2293*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
2294*8975f5c5SAndroid Build Coastguard Worker {
2295*8975f5c5SAndroid Build Coastguard Worker return false;
2296*8975f5c5SAndroid Build Coastguard Worker }
2297*8975f5c5SAndroid Build Coastguard Worker
2298*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
2299*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(columns, writeColumns);
2300*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(rows, writeRows);
2301*8975f5c5SAndroid Build Coastguard Worker
2302*8975f5c5SAndroid Build Coastguard Worker return true;
2303*8975f5c5SAndroid Build Coastguard Worker }
2304*8975f5c5SAndroid Build Coastguard Worker
ValidateReadnPixelsEXT(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)2305*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadnPixelsEXT(const Context *context,
2306*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2307*8975f5c5SAndroid Build Coastguard Worker GLint x,
2308*8975f5c5SAndroid Build Coastguard Worker GLint y,
2309*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
2310*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
2311*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2312*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2313*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2314*8975f5c5SAndroid Build Coastguard Worker const void *pixels)
2315*8975f5c5SAndroid Build Coastguard Worker {
2316*8975f5c5SAndroid Build Coastguard Worker if (bufSize < 0)
2317*8975f5c5SAndroid Build Coastguard Worker {
2318*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
2319*8975f5c5SAndroid Build Coastguard Worker return false;
2320*8975f5c5SAndroid Build Coastguard Worker }
2321*8975f5c5SAndroid Build Coastguard Worker
2322*8975f5c5SAndroid Build Coastguard Worker return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
2323*8975f5c5SAndroid Build Coastguard Worker nullptr, nullptr, nullptr, pixels);
2324*8975f5c5SAndroid Build Coastguard Worker }
2325*8975f5c5SAndroid Build Coastguard Worker
ValidateReadnPixelsRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const GLsizei * length,const GLsizei * columns,const GLsizei * rows,const void * data)2326*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadnPixelsRobustANGLE(const Context *context,
2327*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2328*8975f5c5SAndroid Build Coastguard Worker GLint x,
2329*8975f5c5SAndroid Build Coastguard Worker GLint y,
2330*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
2331*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
2332*8975f5c5SAndroid Build Coastguard Worker GLenum format,
2333*8975f5c5SAndroid Build Coastguard Worker GLenum type,
2334*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2335*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2336*8975f5c5SAndroid Build Coastguard Worker const GLsizei *columns,
2337*8975f5c5SAndroid Build Coastguard Worker const GLsizei *rows,
2338*8975f5c5SAndroid Build Coastguard Worker const void *data)
2339*8975f5c5SAndroid Build Coastguard Worker {
2340*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
2341*8975f5c5SAndroid Build Coastguard Worker GLsizei writeColumns = 0;
2342*8975f5c5SAndroid Build Coastguard Worker GLsizei writeRows = 0;
2343*8975f5c5SAndroid Build Coastguard Worker
2344*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2345*8975f5c5SAndroid Build Coastguard Worker {
2346*8975f5c5SAndroid Build Coastguard Worker return false;
2347*8975f5c5SAndroid Build Coastguard Worker }
2348*8975f5c5SAndroid Build Coastguard Worker
2349*8975f5c5SAndroid Build Coastguard Worker if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
2350*8975f5c5SAndroid Build Coastguard Worker &writeLength, &writeColumns, &writeRows, data))
2351*8975f5c5SAndroid Build Coastguard Worker {
2352*8975f5c5SAndroid Build Coastguard Worker return false;
2353*8975f5c5SAndroid Build Coastguard Worker }
2354*8975f5c5SAndroid Build Coastguard Worker
2355*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
2356*8975f5c5SAndroid Build Coastguard Worker {
2357*8975f5c5SAndroid Build Coastguard Worker return false;
2358*8975f5c5SAndroid Build Coastguard Worker }
2359*8975f5c5SAndroid Build Coastguard Worker
2360*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
2361*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(columns, writeColumns);
2362*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(rows, writeRows);
2363*8975f5c5SAndroid Build Coastguard Worker
2364*8975f5c5SAndroid Build Coastguard Worker return true;
2365*8975f5c5SAndroid Build Coastguard Worker }
2366*8975f5c5SAndroid Build Coastguard Worker
ValidateGenQueriesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const QueryID * ids)2367*8975f5c5SAndroid Build Coastguard Worker bool ValidateGenQueriesEXT(const Context *context,
2368*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2369*8975f5c5SAndroid Build Coastguard Worker GLsizei n,
2370*8975f5c5SAndroid Build Coastguard Worker const QueryID *ids)
2371*8975f5c5SAndroid Build Coastguard Worker {
2372*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().occlusionQueryBooleanEXT &&
2373*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().disjointTimerQueryEXT)
2374*8975f5c5SAndroid Build Coastguard Worker {
2375*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2376*8975f5c5SAndroid Build Coastguard Worker return false;
2377*8975f5c5SAndroid Build Coastguard Worker }
2378*8975f5c5SAndroid Build Coastguard Worker
2379*8975f5c5SAndroid Build Coastguard Worker return ValidateGenOrDelete(context, entryPoint, n);
2380*8975f5c5SAndroid Build Coastguard Worker }
2381*8975f5c5SAndroid Build Coastguard Worker
ValidateDeleteQueriesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const QueryID * ids)2382*8975f5c5SAndroid Build Coastguard Worker bool ValidateDeleteQueriesEXT(const Context *context,
2383*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2384*8975f5c5SAndroid Build Coastguard Worker GLsizei n,
2385*8975f5c5SAndroid Build Coastguard Worker const QueryID *ids)
2386*8975f5c5SAndroid Build Coastguard Worker {
2387*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().occlusionQueryBooleanEXT &&
2388*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().disjointTimerQueryEXT)
2389*8975f5c5SAndroid Build Coastguard Worker {
2390*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2391*8975f5c5SAndroid Build Coastguard Worker return false;
2392*8975f5c5SAndroid Build Coastguard Worker }
2393*8975f5c5SAndroid Build Coastguard Worker
2394*8975f5c5SAndroid Build Coastguard Worker return ValidateGenOrDelete(context, entryPoint, n);
2395*8975f5c5SAndroid Build Coastguard Worker }
2396*8975f5c5SAndroid Build Coastguard Worker
ValidateIsQueryEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id)2397*8975f5c5SAndroid Build Coastguard Worker bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id)
2398*8975f5c5SAndroid Build Coastguard Worker {
2399*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().occlusionQueryBooleanEXT &&
2400*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().disjointTimerQueryEXT)
2401*8975f5c5SAndroid Build Coastguard Worker {
2402*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2403*8975f5c5SAndroid Build Coastguard Worker return false;
2404*8975f5c5SAndroid Build Coastguard Worker }
2405*8975f5c5SAndroid Build Coastguard Worker
2406*8975f5c5SAndroid Build Coastguard Worker return true;
2407*8975f5c5SAndroid Build Coastguard Worker }
2408*8975f5c5SAndroid Build Coastguard Worker
ValidateBeginQueryBase(const Context * context,angle::EntryPoint entryPoint,QueryType target,QueryID id)2409*8975f5c5SAndroid Build Coastguard Worker bool ValidateBeginQueryBase(const Context *context,
2410*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2411*8975f5c5SAndroid Build Coastguard Worker QueryType target,
2412*8975f5c5SAndroid Build Coastguard Worker QueryID id)
2413*8975f5c5SAndroid Build Coastguard Worker {
2414*8975f5c5SAndroid Build Coastguard Worker if (!ValidQueryType(context, target))
2415*8975f5c5SAndroid Build Coastguard Worker {
2416*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryType);
2417*8975f5c5SAndroid Build Coastguard Worker return false;
2418*8975f5c5SAndroid Build Coastguard Worker }
2419*8975f5c5SAndroid Build Coastguard Worker
2420*8975f5c5SAndroid Build Coastguard Worker if (id.value == 0)
2421*8975f5c5SAndroid Build Coastguard Worker {
2422*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2423*8975f5c5SAndroid Build Coastguard Worker return false;
2424*8975f5c5SAndroid Build Coastguard Worker }
2425*8975f5c5SAndroid Build Coastguard Worker
2426*8975f5c5SAndroid Build Coastguard Worker // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
2427*8975f5c5SAndroid Build Coastguard Worker // of zero, if the active query object name for <target> is non-zero (for the
2428*8975f5c5SAndroid Build Coastguard Worker // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
2429*8975f5c5SAndroid Build Coastguard Worker // the active query for either target is non-zero), if <id> is the name of an
2430*8975f5c5SAndroid Build Coastguard Worker // existing query object whose type does not match <target>, or if <id> is the
2431*8975f5c5SAndroid Build Coastguard Worker // active query object name for any query type, the error INVALID_OPERATION is
2432*8975f5c5SAndroid Build Coastguard Worker // generated.
2433*8975f5c5SAndroid Build Coastguard Worker
2434*8975f5c5SAndroid Build Coastguard Worker // Ensure no other queries are active
2435*8975f5c5SAndroid Build Coastguard Worker // NOTE: If other queries than occlusion are supported, we will need to check
2436*8975f5c5SAndroid Build Coastguard Worker // separately that:
2437*8975f5c5SAndroid Build Coastguard Worker // a) The query ID passed is not the current active query for any target/type
2438*8975f5c5SAndroid Build Coastguard Worker // b) There are no active queries for the requested target (and in the case
2439*8975f5c5SAndroid Build Coastguard Worker // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
2440*8975f5c5SAndroid Build Coastguard Worker // no query may be active for either if glBeginQuery targets either.
2441*8975f5c5SAndroid Build Coastguard Worker
2442*8975f5c5SAndroid Build Coastguard Worker if (context->getState().isQueryActive(target))
2443*8975f5c5SAndroid Build Coastguard Worker {
2444*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kOtherQueryActive);
2445*8975f5c5SAndroid Build Coastguard Worker return false;
2446*8975f5c5SAndroid Build Coastguard Worker }
2447*8975f5c5SAndroid Build Coastguard Worker
2448*8975f5c5SAndroid Build Coastguard Worker // check that name was obtained with glGenQueries
2449*8975f5c5SAndroid Build Coastguard Worker if (!context->isQueryGenerated(id))
2450*8975f5c5SAndroid Build Coastguard Worker {
2451*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2452*8975f5c5SAndroid Build Coastguard Worker return false;
2453*8975f5c5SAndroid Build Coastguard Worker }
2454*8975f5c5SAndroid Build Coastguard Worker
2455*8975f5c5SAndroid Build Coastguard Worker // Check for type mismatch. If query is not yet started we're good to go.
2456*8975f5c5SAndroid Build Coastguard Worker Query *queryObject = context->getQuery(id);
2457*8975f5c5SAndroid Build Coastguard Worker if (queryObject && queryObject->getType() != target)
2458*8975f5c5SAndroid Build Coastguard Worker {
2459*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryTargetMismatch);
2460*8975f5c5SAndroid Build Coastguard Worker return false;
2461*8975f5c5SAndroid Build Coastguard Worker }
2462*8975f5c5SAndroid Build Coastguard Worker
2463*8975f5c5SAndroid Build Coastguard Worker return true;
2464*8975f5c5SAndroid Build Coastguard Worker }
2465*8975f5c5SAndroid Build Coastguard Worker
ValidateBeginQueryEXT(const Context * context,angle::EntryPoint entryPoint,QueryType target,QueryID id)2466*8975f5c5SAndroid Build Coastguard Worker bool ValidateBeginQueryEXT(const Context *context,
2467*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2468*8975f5c5SAndroid Build Coastguard Worker QueryType target,
2469*8975f5c5SAndroid Build Coastguard Worker QueryID id)
2470*8975f5c5SAndroid Build Coastguard Worker {
2471*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().occlusionQueryBooleanEXT &&
2472*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().disjointTimerQueryEXT &&
2473*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().syncQueryCHROMIUM)
2474*8975f5c5SAndroid Build Coastguard Worker {
2475*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2476*8975f5c5SAndroid Build Coastguard Worker return false;
2477*8975f5c5SAndroid Build Coastguard Worker }
2478*8975f5c5SAndroid Build Coastguard Worker
2479*8975f5c5SAndroid Build Coastguard Worker return ValidateBeginQueryBase(context, entryPoint, target, id);
2480*8975f5c5SAndroid Build Coastguard Worker }
2481*8975f5c5SAndroid Build Coastguard Worker
ValidateEndQueryBase(const Context * context,angle::EntryPoint entryPoint,QueryType target)2482*8975f5c5SAndroid Build Coastguard Worker bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target)
2483*8975f5c5SAndroid Build Coastguard Worker {
2484*8975f5c5SAndroid Build Coastguard Worker if (!ValidQueryType(context, target))
2485*8975f5c5SAndroid Build Coastguard Worker {
2486*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryType);
2487*8975f5c5SAndroid Build Coastguard Worker return false;
2488*8975f5c5SAndroid Build Coastguard Worker }
2489*8975f5c5SAndroid Build Coastguard Worker
2490*8975f5c5SAndroid Build Coastguard Worker const Query *queryObject = context->getState().getActiveQuery(target);
2491*8975f5c5SAndroid Build Coastguard Worker
2492*8975f5c5SAndroid Build Coastguard Worker if (queryObject == nullptr)
2493*8975f5c5SAndroid Build Coastguard Worker {
2494*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryInactive);
2495*8975f5c5SAndroid Build Coastguard Worker return false;
2496*8975f5c5SAndroid Build Coastguard Worker }
2497*8975f5c5SAndroid Build Coastguard Worker
2498*8975f5c5SAndroid Build Coastguard Worker return true;
2499*8975f5c5SAndroid Build Coastguard Worker }
2500*8975f5c5SAndroid Build Coastguard Worker
ValidateEndQueryEXT(const Context * context,angle::EntryPoint entryPoint,QueryType target)2501*8975f5c5SAndroid Build Coastguard Worker bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target)
2502*8975f5c5SAndroid Build Coastguard Worker {
2503*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().occlusionQueryBooleanEXT &&
2504*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().disjointTimerQueryEXT &&
2505*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().syncQueryCHROMIUM)
2506*8975f5c5SAndroid Build Coastguard Worker {
2507*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2508*8975f5c5SAndroid Build Coastguard Worker return false;
2509*8975f5c5SAndroid Build Coastguard Worker }
2510*8975f5c5SAndroid Build Coastguard Worker
2511*8975f5c5SAndroid Build Coastguard Worker return ValidateEndQueryBase(context, entryPoint, target);
2512*8975f5c5SAndroid Build Coastguard Worker }
2513*8975f5c5SAndroid Build Coastguard Worker
ValidateQueryCounterEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,QueryType target)2514*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryCounterEXT(const Context *context,
2515*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2516*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2517*8975f5c5SAndroid Build Coastguard Worker QueryType target)
2518*8975f5c5SAndroid Build Coastguard Worker {
2519*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2520*8975f5c5SAndroid Build Coastguard Worker {
2521*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2522*8975f5c5SAndroid Build Coastguard Worker return false;
2523*8975f5c5SAndroid Build Coastguard Worker }
2524*8975f5c5SAndroid Build Coastguard Worker
2525*8975f5c5SAndroid Build Coastguard Worker if (target != QueryType::Timestamp)
2526*8975f5c5SAndroid Build Coastguard Worker {
2527*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryTarget);
2528*8975f5c5SAndroid Build Coastguard Worker return false;
2529*8975f5c5SAndroid Build Coastguard Worker }
2530*8975f5c5SAndroid Build Coastguard Worker
2531*8975f5c5SAndroid Build Coastguard Worker if (!context->isQueryGenerated(id))
2532*8975f5c5SAndroid Build Coastguard Worker {
2533*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2534*8975f5c5SAndroid Build Coastguard Worker return false;
2535*8975f5c5SAndroid Build Coastguard Worker }
2536*8975f5c5SAndroid Build Coastguard Worker
2537*8975f5c5SAndroid Build Coastguard Worker // If query object is not started, that's fine.
2538*8975f5c5SAndroid Build Coastguard Worker Query *queryObject = context->getQuery(id);
2539*8975f5c5SAndroid Build Coastguard Worker if (queryObject && context->getState().isQueryActive(queryObject))
2540*8975f5c5SAndroid Build Coastguard Worker {
2541*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryActive);
2542*8975f5c5SAndroid Build Coastguard Worker return false;
2543*8975f5c5SAndroid Build Coastguard Worker }
2544*8975f5c5SAndroid Build Coastguard Worker
2545*8975f5c5SAndroid Build Coastguard Worker return true;
2546*8975f5c5SAndroid Build Coastguard Worker }
2547*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryivBase(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,GLsizei * numParams)2548*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryivBase(const Context *context,
2549*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2550*8975f5c5SAndroid Build Coastguard Worker QueryType target,
2551*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2552*8975f5c5SAndroid Build Coastguard Worker GLsizei *numParams)
2553*8975f5c5SAndroid Build Coastguard Worker {
2554*8975f5c5SAndroid Build Coastguard Worker if (numParams)
2555*8975f5c5SAndroid Build Coastguard Worker {
2556*8975f5c5SAndroid Build Coastguard Worker *numParams = 0;
2557*8975f5c5SAndroid Build Coastguard Worker }
2558*8975f5c5SAndroid Build Coastguard Worker
2559*8975f5c5SAndroid Build Coastguard Worker if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
2560*8975f5c5SAndroid Build Coastguard Worker {
2561*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryType);
2562*8975f5c5SAndroid Build Coastguard Worker return false;
2563*8975f5c5SAndroid Build Coastguard Worker }
2564*8975f5c5SAndroid Build Coastguard Worker
2565*8975f5c5SAndroid Build Coastguard Worker switch (pname)
2566*8975f5c5SAndroid Build Coastguard Worker {
2567*8975f5c5SAndroid Build Coastguard Worker case GL_CURRENT_QUERY_EXT:
2568*8975f5c5SAndroid Build Coastguard Worker if (target == QueryType::Timestamp)
2569*8975f5c5SAndroid Build Coastguard Worker {
2570*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryTarget);
2571*8975f5c5SAndroid Build Coastguard Worker return false;
2572*8975f5c5SAndroid Build Coastguard Worker }
2573*8975f5c5SAndroid Build Coastguard Worker break;
2574*8975f5c5SAndroid Build Coastguard Worker case GL_QUERY_COUNTER_BITS_EXT:
2575*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT ||
2576*8975f5c5SAndroid Build Coastguard Worker (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
2577*8975f5c5SAndroid Build Coastguard Worker {
2578*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2579*8975f5c5SAndroid Build Coastguard Worker return false;
2580*8975f5c5SAndroid Build Coastguard Worker }
2581*8975f5c5SAndroid Build Coastguard Worker break;
2582*8975f5c5SAndroid Build Coastguard Worker default:
2583*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2584*8975f5c5SAndroid Build Coastguard Worker return false;
2585*8975f5c5SAndroid Build Coastguard Worker }
2586*8975f5c5SAndroid Build Coastguard Worker
2587*8975f5c5SAndroid Build Coastguard Worker if (numParams)
2588*8975f5c5SAndroid Build Coastguard Worker {
2589*8975f5c5SAndroid Build Coastguard Worker // All queries return only one value
2590*8975f5c5SAndroid Build Coastguard Worker *numParams = 1;
2591*8975f5c5SAndroid Build Coastguard Worker }
2592*8975f5c5SAndroid Build Coastguard Worker
2593*8975f5c5SAndroid Build Coastguard Worker return true;
2594*8975f5c5SAndroid Build Coastguard Worker }
2595*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryivEXT(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,const GLint * params)2596*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryivEXT(const Context *context,
2597*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2598*8975f5c5SAndroid Build Coastguard Worker QueryType target,
2599*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2600*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
2601*8975f5c5SAndroid Build Coastguard Worker {
2602*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().occlusionQueryBooleanEXT &&
2603*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().disjointTimerQueryEXT &&
2604*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().syncQueryCHROMIUM)
2605*8975f5c5SAndroid Build Coastguard Worker {
2606*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2607*8975f5c5SAndroid Build Coastguard Worker return false;
2608*8975f5c5SAndroid Build Coastguard Worker }
2609*8975f5c5SAndroid Build Coastguard Worker
2610*8975f5c5SAndroid Build Coastguard Worker return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr);
2611*8975f5c5SAndroid Build Coastguard Worker }
2612*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2613*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryivRobustANGLE(const Context *context,
2614*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2615*8975f5c5SAndroid Build Coastguard Worker QueryType target,
2616*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2617*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2618*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2619*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
2620*8975f5c5SAndroid Build Coastguard Worker {
2621*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2622*8975f5c5SAndroid Build Coastguard Worker {
2623*8975f5c5SAndroid Build Coastguard Worker return false;
2624*8975f5c5SAndroid Build Coastguard Worker }
2625*8975f5c5SAndroid Build Coastguard Worker
2626*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
2627*8975f5c5SAndroid Build Coastguard Worker
2628*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetQueryivBase(context, entryPoint, target, pname, &numParams))
2629*8975f5c5SAndroid Build Coastguard Worker {
2630*8975f5c5SAndroid Build Coastguard Worker return false;
2631*8975f5c5SAndroid Build Coastguard Worker }
2632*8975f5c5SAndroid Build Coastguard Worker
2633*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2634*8975f5c5SAndroid Build Coastguard Worker {
2635*8975f5c5SAndroid Build Coastguard Worker return false;
2636*8975f5c5SAndroid Build Coastguard Worker }
2637*8975f5c5SAndroid Build Coastguard Worker
2638*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
2639*8975f5c5SAndroid Build Coastguard Worker
2640*8975f5c5SAndroid Build Coastguard Worker return true;
2641*8975f5c5SAndroid Build Coastguard Worker }
2642*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectValueBase(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei * numParams)2643*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectValueBase(const Context *context,
2644*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2645*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2646*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2647*8975f5c5SAndroid Build Coastguard Worker GLsizei *numParams)
2648*8975f5c5SAndroid Build Coastguard Worker {
2649*8975f5c5SAndroid Build Coastguard Worker if (numParams)
2650*8975f5c5SAndroid Build Coastguard Worker {
2651*8975f5c5SAndroid Build Coastguard Worker *numParams = 1;
2652*8975f5c5SAndroid Build Coastguard Worker }
2653*8975f5c5SAndroid Build Coastguard Worker
2654*8975f5c5SAndroid Build Coastguard Worker if (context->isContextLost())
2655*8975f5c5SAndroid Build Coastguard Worker {
2656*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
2657*8975f5c5SAndroid Build Coastguard Worker
2658*8975f5c5SAndroid Build Coastguard Worker if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
2659*8975f5c5SAndroid Build Coastguard Worker {
2660*8975f5c5SAndroid Build Coastguard Worker // Generate an error but still return true, the context still needs to return a
2661*8975f5c5SAndroid Build Coastguard Worker // value in this case.
2662*8975f5c5SAndroid Build Coastguard Worker return true;
2663*8975f5c5SAndroid Build Coastguard Worker }
2664*8975f5c5SAndroid Build Coastguard Worker else
2665*8975f5c5SAndroid Build Coastguard Worker {
2666*8975f5c5SAndroid Build Coastguard Worker return false;
2667*8975f5c5SAndroid Build Coastguard Worker }
2668*8975f5c5SAndroid Build Coastguard Worker }
2669*8975f5c5SAndroid Build Coastguard Worker
2670*8975f5c5SAndroid Build Coastguard Worker Query *queryObject = context->getQuery(id);
2671*8975f5c5SAndroid Build Coastguard Worker
2672*8975f5c5SAndroid Build Coastguard Worker if (!queryObject)
2673*8975f5c5SAndroid Build Coastguard Worker {
2674*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2675*8975f5c5SAndroid Build Coastguard Worker return false;
2676*8975f5c5SAndroid Build Coastguard Worker }
2677*8975f5c5SAndroid Build Coastguard Worker
2678*8975f5c5SAndroid Build Coastguard Worker if (context->getState().isQueryActive(queryObject))
2679*8975f5c5SAndroid Build Coastguard Worker {
2680*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryActive);
2681*8975f5c5SAndroid Build Coastguard Worker return false;
2682*8975f5c5SAndroid Build Coastguard Worker }
2683*8975f5c5SAndroid Build Coastguard Worker
2684*8975f5c5SAndroid Build Coastguard Worker switch (pname)
2685*8975f5c5SAndroid Build Coastguard Worker {
2686*8975f5c5SAndroid Build Coastguard Worker case GL_QUERY_RESULT_EXT:
2687*8975f5c5SAndroid Build Coastguard Worker case GL_QUERY_RESULT_AVAILABLE_EXT:
2688*8975f5c5SAndroid Build Coastguard Worker break;
2689*8975f5c5SAndroid Build Coastguard Worker
2690*8975f5c5SAndroid Build Coastguard Worker default:
2691*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2692*8975f5c5SAndroid Build Coastguard Worker return false;
2693*8975f5c5SAndroid Build Coastguard Worker }
2694*8975f5c5SAndroid Build Coastguard Worker
2695*8975f5c5SAndroid Build Coastguard Worker return true;
2696*8975f5c5SAndroid Build Coastguard Worker }
2697*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectivEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,const GLint * params)2698*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectivEXT(const Context *context,
2699*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2700*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2701*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2702*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
2703*8975f5c5SAndroid Build Coastguard Worker {
2704*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2705*8975f5c5SAndroid Build Coastguard Worker {
2706*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2707*8975f5c5SAndroid Build Coastguard Worker return false;
2708*8975f5c5SAndroid Build Coastguard Worker }
2709*8975f5c5SAndroid Build Coastguard Worker return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2710*8975f5c5SAndroid Build Coastguard Worker }
2711*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2712*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
2713*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2714*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2715*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2716*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2717*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2718*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
2719*8975f5c5SAndroid Build Coastguard Worker {
2720*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2721*8975f5c5SAndroid Build Coastguard Worker {
2722*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2723*8975f5c5SAndroid Build Coastguard Worker return false;
2724*8975f5c5SAndroid Build Coastguard Worker }
2725*8975f5c5SAndroid Build Coastguard Worker
2726*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2727*8975f5c5SAndroid Build Coastguard Worker {
2728*8975f5c5SAndroid Build Coastguard Worker return false;
2729*8975f5c5SAndroid Build Coastguard Worker }
2730*8975f5c5SAndroid Build Coastguard Worker
2731*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
2732*8975f5c5SAndroid Build Coastguard Worker
2733*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2734*8975f5c5SAndroid Build Coastguard Worker {
2735*8975f5c5SAndroid Build Coastguard Worker return false;
2736*8975f5c5SAndroid Build Coastguard Worker }
2737*8975f5c5SAndroid Build Coastguard Worker
2738*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2739*8975f5c5SAndroid Build Coastguard Worker {
2740*8975f5c5SAndroid Build Coastguard Worker return false;
2741*8975f5c5SAndroid Build Coastguard Worker }
2742*8975f5c5SAndroid Build Coastguard Worker
2743*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
2744*8975f5c5SAndroid Build Coastguard Worker
2745*8975f5c5SAndroid Build Coastguard Worker return true;
2746*8975f5c5SAndroid Build Coastguard Worker }
2747*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectuivEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,const GLuint * params)2748*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectuivEXT(const Context *context,
2749*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2750*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2751*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2752*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
2753*8975f5c5SAndroid Build Coastguard Worker {
2754*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT &&
2755*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().occlusionQueryBooleanEXT &&
2756*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().syncQueryCHROMIUM)
2757*8975f5c5SAndroid Build Coastguard Worker {
2758*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2759*8975f5c5SAndroid Build Coastguard Worker return false;
2760*8975f5c5SAndroid Build Coastguard Worker }
2761*8975f5c5SAndroid Build Coastguard Worker return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2762*8975f5c5SAndroid Build Coastguard Worker }
2763*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)2764*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
2765*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2766*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2767*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2768*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2769*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2770*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
2771*8975f5c5SAndroid Build Coastguard Worker {
2772*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT &&
2773*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().occlusionQueryBooleanEXT &&
2774*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().syncQueryCHROMIUM)
2775*8975f5c5SAndroid Build Coastguard Worker {
2776*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2777*8975f5c5SAndroid Build Coastguard Worker return false;
2778*8975f5c5SAndroid Build Coastguard Worker }
2779*8975f5c5SAndroid Build Coastguard Worker
2780*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2781*8975f5c5SAndroid Build Coastguard Worker {
2782*8975f5c5SAndroid Build Coastguard Worker return false;
2783*8975f5c5SAndroid Build Coastguard Worker }
2784*8975f5c5SAndroid Build Coastguard Worker
2785*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
2786*8975f5c5SAndroid Build Coastguard Worker
2787*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2788*8975f5c5SAndroid Build Coastguard Worker {
2789*8975f5c5SAndroid Build Coastguard Worker return false;
2790*8975f5c5SAndroid Build Coastguard Worker }
2791*8975f5c5SAndroid Build Coastguard Worker
2792*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2793*8975f5c5SAndroid Build Coastguard Worker {
2794*8975f5c5SAndroid Build Coastguard Worker return false;
2795*8975f5c5SAndroid Build Coastguard Worker }
2796*8975f5c5SAndroid Build Coastguard Worker
2797*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
2798*8975f5c5SAndroid Build Coastguard Worker
2799*8975f5c5SAndroid Build Coastguard Worker return true;
2800*8975f5c5SAndroid Build Coastguard Worker }
2801*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjecti64vEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLint64 * params)2802*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjecti64vEXT(const Context *context,
2803*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2804*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2805*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2806*8975f5c5SAndroid Build Coastguard Worker GLint64 *params)
2807*8975f5c5SAndroid Build Coastguard Worker {
2808*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2809*8975f5c5SAndroid Build Coastguard Worker {
2810*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2811*8975f5c5SAndroid Build Coastguard Worker return false;
2812*8975f5c5SAndroid Build Coastguard Worker }
2813*8975f5c5SAndroid Build Coastguard Worker return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2814*8975f5c5SAndroid Build Coastguard Worker }
2815*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjecti64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,GLint64 * params)2816*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
2817*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2818*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2819*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2820*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2821*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2822*8975f5c5SAndroid Build Coastguard Worker GLint64 *params)
2823*8975f5c5SAndroid Build Coastguard Worker {
2824*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2825*8975f5c5SAndroid Build Coastguard Worker {
2826*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2827*8975f5c5SAndroid Build Coastguard Worker return false;
2828*8975f5c5SAndroid Build Coastguard Worker }
2829*8975f5c5SAndroid Build Coastguard Worker
2830*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2831*8975f5c5SAndroid Build Coastguard Worker {
2832*8975f5c5SAndroid Build Coastguard Worker return false;
2833*8975f5c5SAndroid Build Coastguard Worker }
2834*8975f5c5SAndroid Build Coastguard Worker
2835*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
2836*8975f5c5SAndroid Build Coastguard Worker
2837*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2838*8975f5c5SAndroid Build Coastguard Worker {
2839*8975f5c5SAndroid Build Coastguard Worker return false;
2840*8975f5c5SAndroid Build Coastguard Worker }
2841*8975f5c5SAndroid Build Coastguard Worker
2842*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2843*8975f5c5SAndroid Build Coastguard Worker {
2844*8975f5c5SAndroid Build Coastguard Worker return false;
2845*8975f5c5SAndroid Build Coastguard Worker }
2846*8975f5c5SAndroid Build Coastguard Worker
2847*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
2848*8975f5c5SAndroid Build Coastguard Worker
2849*8975f5c5SAndroid Build Coastguard Worker return true;
2850*8975f5c5SAndroid Build Coastguard Worker }
2851*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectui64vEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLuint64 * params)2852*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectui64vEXT(const Context *context,
2853*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2854*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2855*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2856*8975f5c5SAndroid Build Coastguard Worker GLuint64 *params)
2857*8975f5c5SAndroid Build Coastguard Worker {
2858*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2859*8975f5c5SAndroid Build Coastguard Worker {
2860*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2861*8975f5c5SAndroid Build Coastguard Worker return false;
2862*8975f5c5SAndroid Build Coastguard Worker }
2863*8975f5c5SAndroid Build Coastguard Worker return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2864*8975f5c5SAndroid Build Coastguard Worker }
2865*8975f5c5SAndroid Build Coastguard Worker
ValidateGetQueryObjectui64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,GLuint64 * params)2866*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
2867*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2868*8975f5c5SAndroid Build Coastguard Worker QueryID id,
2869*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
2870*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
2871*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
2872*8975f5c5SAndroid Build Coastguard Worker GLuint64 *params)
2873*8975f5c5SAndroid Build Coastguard Worker {
2874*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().disjointTimerQueryEXT)
2875*8975f5c5SAndroid Build Coastguard Worker {
2876*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2877*8975f5c5SAndroid Build Coastguard Worker return false;
2878*8975f5c5SAndroid Build Coastguard Worker }
2879*8975f5c5SAndroid Build Coastguard Worker
2880*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2881*8975f5c5SAndroid Build Coastguard Worker {
2882*8975f5c5SAndroid Build Coastguard Worker return false;
2883*8975f5c5SAndroid Build Coastguard Worker }
2884*8975f5c5SAndroid Build Coastguard Worker
2885*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
2886*8975f5c5SAndroid Build Coastguard Worker
2887*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2888*8975f5c5SAndroid Build Coastguard Worker {
2889*8975f5c5SAndroid Build Coastguard Worker return false;
2890*8975f5c5SAndroid Build Coastguard Worker }
2891*8975f5c5SAndroid Build Coastguard Worker
2892*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2893*8975f5c5SAndroid Build Coastguard Worker {
2894*8975f5c5SAndroid Build Coastguard Worker return false;
2895*8975f5c5SAndroid Build Coastguard Worker }
2896*8975f5c5SAndroid Build Coastguard Worker
2897*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
2898*8975f5c5SAndroid Build Coastguard Worker
2899*8975f5c5SAndroid Build Coastguard Worker return true;
2900*8975f5c5SAndroid Build Coastguard Worker }
2901*8975f5c5SAndroid Build Coastguard Worker
ValidateUniformCommonBase(const Context * context,angle::EntryPoint entryPoint,const Program * program,UniformLocation location,GLsizei count,const LinkedUniform ** uniformOut)2902*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniformCommonBase(const Context *context,
2903*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2904*8975f5c5SAndroid Build Coastguard Worker const Program *program,
2905*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
2906*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2907*8975f5c5SAndroid Build Coastguard Worker const LinkedUniform **uniformOut)
2908*8975f5c5SAndroid Build Coastguard Worker {
2909*8975f5c5SAndroid Build Coastguard Worker // TODO(Jiajia): Add image uniform check in future.
2910*8975f5c5SAndroid Build Coastguard Worker if (count < 0)
2911*8975f5c5SAndroid Build Coastguard Worker {
2912*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
2913*8975f5c5SAndroid Build Coastguard Worker return false;
2914*8975f5c5SAndroid Build Coastguard Worker }
2915*8975f5c5SAndroid Build Coastguard Worker
2916*8975f5c5SAndroid Build Coastguard Worker if (!program)
2917*8975f5c5SAndroid Build Coastguard Worker {
2918*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramName);
2919*8975f5c5SAndroid Build Coastguard Worker return false;
2920*8975f5c5SAndroid Build Coastguard Worker }
2921*8975f5c5SAndroid Build Coastguard Worker
2922*8975f5c5SAndroid Build Coastguard Worker if (!program->isLinked())
2923*8975f5c5SAndroid Build Coastguard Worker {
2924*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
2925*8975f5c5SAndroid Build Coastguard Worker return false;
2926*8975f5c5SAndroid Build Coastguard Worker }
2927*8975f5c5SAndroid Build Coastguard Worker
2928*8975f5c5SAndroid Build Coastguard Worker if (location.value == -1)
2929*8975f5c5SAndroid Build Coastguard Worker {
2930*8975f5c5SAndroid Build Coastguard Worker // Silently ignore the uniform command
2931*8975f5c5SAndroid Build Coastguard Worker return false;
2932*8975f5c5SAndroid Build Coastguard Worker }
2933*8975f5c5SAndroid Build Coastguard Worker
2934*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &executable = program->getExecutable();
2935*8975f5c5SAndroid Build Coastguard Worker const auto &uniformLocations = executable.getUniformLocations();
2936*8975f5c5SAndroid Build Coastguard Worker size_t castedLocation = static_cast<size_t>(location.value);
2937*8975f5c5SAndroid Build Coastguard Worker if (castedLocation >= uniformLocations.size())
2938*8975f5c5SAndroid Build Coastguard Worker {
2939*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformLocation);
2940*8975f5c5SAndroid Build Coastguard Worker return false;
2941*8975f5c5SAndroid Build Coastguard Worker }
2942*8975f5c5SAndroid Build Coastguard Worker
2943*8975f5c5SAndroid Build Coastguard Worker const auto &uniformLocation = uniformLocations[castedLocation];
2944*8975f5c5SAndroid Build Coastguard Worker if (uniformLocation.ignored)
2945*8975f5c5SAndroid Build Coastguard Worker {
2946*8975f5c5SAndroid Build Coastguard Worker // Silently ignore the uniform command
2947*8975f5c5SAndroid Build Coastguard Worker return false;
2948*8975f5c5SAndroid Build Coastguard Worker }
2949*8975f5c5SAndroid Build Coastguard Worker
2950*8975f5c5SAndroid Build Coastguard Worker if (!uniformLocation.used())
2951*8975f5c5SAndroid Build Coastguard Worker {
2952*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformLocation);
2953*8975f5c5SAndroid Build Coastguard Worker return false;
2954*8975f5c5SAndroid Build Coastguard Worker }
2955*8975f5c5SAndroid Build Coastguard Worker
2956*8975f5c5SAndroid Build Coastguard Worker const LinkedUniform &uniform = executable.getUniformByIndex(uniformLocation.index);
2957*8975f5c5SAndroid Build Coastguard Worker
2958*8975f5c5SAndroid Build Coastguard Worker // attempting to write an array to a non-array uniform is an INVALID_OPERATION
2959*8975f5c5SAndroid Build Coastguard Worker if (count > 1 && !uniform.isArray())
2960*8975f5c5SAndroid Build Coastguard Worker {
2961*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformCount);
2962*8975f5c5SAndroid Build Coastguard Worker return false;
2963*8975f5c5SAndroid Build Coastguard Worker }
2964*8975f5c5SAndroid Build Coastguard Worker
2965*8975f5c5SAndroid Build Coastguard Worker *uniformOut = &uniform;
2966*8975f5c5SAndroid Build Coastguard Worker return true;
2967*8975f5c5SAndroid Build Coastguard Worker }
2968*8975f5c5SAndroid Build Coastguard Worker
ValidateUniform1ivValue(const Context * context,angle::EntryPoint entryPoint,GLenum uniformType,GLsizei count,const GLint * value)2969*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniform1ivValue(const Context *context,
2970*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
2971*8975f5c5SAndroid Build Coastguard Worker GLenum uniformType,
2972*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
2973*8975f5c5SAndroid Build Coastguard Worker const GLint *value)
2974*8975f5c5SAndroid Build Coastguard Worker {
2975*8975f5c5SAndroid Build Coastguard Worker // Value type is GL_INT, because we only get here from glUniform1i{v}.
2976*8975f5c5SAndroid Build Coastguard Worker // It is compatible with INT or BOOL.
2977*8975f5c5SAndroid Build Coastguard Worker // Do these cheap tests first, for a little extra speed.
2978*8975f5c5SAndroid Build Coastguard Worker if (GL_INT == uniformType || GL_BOOL == uniformType)
2979*8975f5c5SAndroid Build Coastguard Worker {
2980*8975f5c5SAndroid Build Coastguard Worker return true;
2981*8975f5c5SAndroid Build Coastguard Worker }
2982*8975f5c5SAndroid Build Coastguard Worker
2983*8975f5c5SAndroid Build Coastguard Worker if (IsSamplerType(uniformType))
2984*8975f5c5SAndroid Build Coastguard Worker {
2985*8975f5c5SAndroid Build Coastguard Worker // Check that the values are in range.
2986*8975f5c5SAndroid Build Coastguard Worker const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2987*8975f5c5SAndroid Build Coastguard Worker for (GLsizei i = 0; i < count; ++i)
2988*8975f5c5SAndroid Build Coastguard Worker {
2989*8975f5c5SAndroid Build Coastguard Worker if (value[i] < 0 || value[i] >= max)
2990*8975f5c5SAndroid Build Coastguard Worker {
2991*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplerUniformValueOutOfRange);
2992*8975f5c5SAndroid Build Coastguard Worker return false;
2993*8975f5c5SAndroid Build Coastguard Worker }
2994*8975f5c5SAndroid Build Coastguard Worker }
2995*8975f5c5SAndroid Build Coastguard Worker return true;
2996*8975f5c5SAndroid Build Coastguard Worker }
2997*8975f5c5SAndroid Build Coastguard Worker
2998*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUniformTypeMismatch);
2999*8975f5c5SAndroid Build Coastguard Worker return false;
3000*8975f5c5SAndroid Build Coastguard Worker }
3001*8975f5c5SAndroid Build Coastguard Worker
ValidateUniformMatrixValue(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,GLenum uniformType)3002*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniformMatrixValue(const Context *context,
3003*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3004*8975f5c5SAndroid Build Coastguard Worker GLenum valueType,
3005*8975f5c5SAndroid Build Coastguard Worker GLenum uniformType)
3006*8975f5c5SAndroid Build Coastguard Worker {
3007*8975f5c5SAndroid Build Coastguard Worker // Check that the value type is compatible with uniform type.
3008*8975f5c5SAndroid Build Coastguard Worker if (valueType == uniformType)
3009*8975f5c5SAndroid Build Coastguard Worker {
3010*8975f5c5SAndroid Build Coastguard Worker return true;
3011*8975f5c5SAndroid Build Coastguard Worker }
3012*8975f5c5SAndroid Build Coastguard Worker
3013*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUniformTypeMismatch);
3014*8975f5c5SAndroid Build Coastguard Worker return false;
3015*8975f5c5SAndroid Build Coastguard Worker }
3016*8975f5c5SAndroid Build Coastguard Worker
ValidateUniform(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,UniformLocation location,GLsizei count)3017*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniform(const Context *context,
3018*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3019*8975f5c5SAndroid Build Coastguard Worker GLenum valueType,
3020*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
3021*8975f5c5SAndroid Build Coastguard Worker GLsizei count)
3022*8975f5c5SAndroid Build Coastguard Worker {
3023*8975f5c5SAndroid Build Coastguard Worker const LinkedUniform *uniform = nullptr;
3024*8975f5c5SAndroid Build Coastguard Worker Program *programObject = context->getActiveLinkedProgram();
3025*8975f5c5SAndroid Build Coastguard Worker return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
3026*8975f5c5SAndroid Build Coastguard Worker &uniform) &&
3027*8975f5c5SAndroid Build Coastguard Worker ValidateUniformValue(context, entryPoint, valueType, uniform->getType());
3028*8975f5c5SAndroid Build Coastguard Worker }
3029*8975f5c5SAndroid Build Coastguard Worker
ValidateUniform1iv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLint * value)3030*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniform1iv(const Context *context,
3031*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3032*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
3033*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
3034*8975f5c5SAndroid Build Coastguard Worker const GLint *value)
3035*8975f5c5SAndroid Build Coastguard Worker {
3036*8975f5c5SAndroid Build Coastguard Worker const LinkedUniform *uniform = nullptr;
3037*8975f5c5SAndroid Build Coastguard Worker Program *programObject = context->getActiveLinkedProgram();
3038*8975f5c5SAndroid Build Coastguard Worker return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
3039*8975f5c5SAndroid Build Coastguard Worker &uniform) &&
3040*8975f5c5SAndroid Build Coastguard Worker ValidateUniform1ivValue(context, entryPoint, uniform->getType(), count, value);
3041*8975f5c5SAndroid Build Coastguard Worker }
3042*8975f5c5SAndroid Build Coastguard Worker
ValidateUniformMatrix(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,UniformLocation location,GLsizei count,GLboolean transpose)3043*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniformMatrix(const Context *context,
3044*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3045*8975f5c5SAndroid Build Coastguard Worker GLenum valueType,
3046*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
3047*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
3048*8975f5c5SAndroid Build Coastguard Worker GLboolean transpose)
3049*8975f5c5SAndroid Build Coastguard Worker {
3050*8975f5c5SAndroid Build Coastguard Worker if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
3051*8975f5c5SAndroid Build Coastguard Worker {
3052*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kES3Required);
3053*8975f5c5SAndroid Build Coastguard Worker return false;
3054*8975f5c5SAndroid Build Coastguard Worker }
3055*8975f5c5SAndroid Build Coastguard Worker
3056*8975f5c5SAndroid Build Coastguard Worker const LinkedUniform *uniform = nullptr;
3057*8975f5c5SAndroid Build Coastguard Worker Program *programObject = context->getActiveLinkedProgram();
3058*8975f5c5SAndroid Build Coastguard Worker return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
3059*8975f5c5SAndroid Build Coastguard Worker &uniform) &&
3060*8975f5c5SAndroid Build Coastguard Worker ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->getType());
3061*8975f5c5SAndroid Build Coastguard Worker }
3062*8975f5c5SAndroid Build Coastguard Worker
ValidateStateQuery(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLenum * nativeType,unsigned int * numParams)3063*8975f5c5SAndroid Build Coastguard Worker bool ValidateStateQuery(const Context *context,
3064*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3065*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
3066*8975f5c5SAndroid Build Coastguard Worker GLenum *nativeType,
3067*8975f5c5SAndroid Build Coastguard Worker unsigned int *numParams)
3068*8975f5c5SAndroid Build Coastguard Worker {
3069*8975f5c5SAndroid Build Coastguard Worker if (!context->getQueryParameterInfo(pname, nativeType, numParams))
3070*8975f5c5SAndroid Build Coastguard Worker {
3071*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
3072*8975f5c5SAndroid Build Coastguard Worker return false;
3073*8975f5c5SAndroid Build Coastguard Worker }
3074*8975f5c5SAndroid Build Coastguard Worker
3075*8975f5c5SAndroid Build Coastguard Worker const Caps &caps = context->getCaps();
3076*8975f5c5SAndroid Build Coastguard Worker
3077*8975f5c5SAndroid Build Coastguard Worker if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
3078*8975f5c5SAndroid Build Coastguard Worker {
3079*8975f5c5SAndroid Build Coastguard Worker int colorAttachment = (pname - GL_DRAW_BUFFER0);
3080*8975f5c5SAndroid Build Coastguard Worker
3081*8975f5c5SAndroid Build Coastguard Worker if (colorAttachment >= caps.maxDrawBuffers)
3082*8975f5c5SAndroid Build Coastguard Worker {
3083*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
3084*8975f5c5SAndroid Build Coastguard Worker return false;
3085*8975f5c5SAndroid Build Coastguard Worker }
3086*8975f5c5SAndroid Build Coastguard Worker }
3087*8975f5c5SAndroid Build Coastguard Worker
3088*8975f5c5SAndroid Build Coastguard Worker switch (pname)
3089*8975f5c5SAndroid Build Coastguard Worker {
3090*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_2D:
3091*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_CUBE_MAP:
3092*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_3D:
3093*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_2D_ARRAY:
3094*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
3095*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
3096*8975f5c5SAndroid Build Coastguard Worker break;
3097*8975f5c5SAndroid Build Coastguard Worker
3098*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
3099*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureRectangleANGLE)
3100*8975f5c5SAndroid Build Coastguard Worker {
3101*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3102*8975f5c5SAndroid Build Coastguard Worker return false;
3103*8975f5c5SAndroid Build Coastguard Worker }
3104*8975f5c5SAndroid Build Coastguard Worker break;
3105*8975f5c5SAndroid Build Coastguard Worker
3106*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_EXTERNAL_OES:
3107*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().EGLStreamConsumerExternalNV &&
3108*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().EGLImageExternalOES)
3109*8975f5c5SAndroid Build Coastguard Worker {
3110*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3111*8975f5c5SAndroid Build Coastguard Worker return false;
3112*8975f5c5SAndroid Build Coastguard Worker }
3113*8975f5c5SAndroid Build Coastguard Worker break;
3114*8975f5c5SAndroid Build Coastguard Worker
3115*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER_BINDING:
3116*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BINDING_BUFFER:
3117*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
3118*8975f5c5SAndroid Build Coastguard Worker case GL_MAX_TEXTURE_BUFFER_SIZE:
3119*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 2) &&
3120*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().textureBufferAny())
3121*8975f5c5SAndroid Build Coastguard Worker {
3122*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferExtensionNotAvailable);
3123*8975f5c5SAndroid Build Coastguard Worker return false;
3124*8975f5c5SAndroid Build Coastguard Worker }
3125*8975f5c5SAndroid Build Coastguard Worker break;
3126*8975f5c5SAndroid Build Coastguard Worker
3127*8975f5c5SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3128*8975f5c5SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3129*8975f5c5SAndroid Build Coastguard Worker {
3130*8975f5c5SAndroid Build Coastguard Worker Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
3131*8975f5c5SAndroid Build Coastguard Worker ASSERT(readFramebuffer);
3132*8975f5c5SAndroid Build Coastguard Worker
3133*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, entryPoint,
3134*8975f5c5SAndroid Build Coastguard Worker readFramebuffer))
3135*8975f5c5SAndroid Build Coastguard Worker {
3136*8975f5c5SAndroid Build Coastguard Worker return false;
3137*8975f5c5SAndroid Build Coastguard Worker }
3138*8975f5c5SAndroid Build Coastguard Worker
3139*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->getReadBufferState() == GL_NONE)
3140*8975f5c5SAndroid Build Coastguard Worker {
3141*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNone);
3142*8975f5c5SAndroid Build Coastguard Worker return false;
3143*8975f5c5SAndroid Build Coastguard Worker }
3144*8975f5c5SAndroid Build Coastguard Worker
3145*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *attachment = readFramebuffer->getReadColorAttachment();
3146*8975f5c5SAndroid Build Coastguard Worker if (!attachment)
3147*8975f5c5SAndroid Build Coastguard Worker {
3148*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNotAttached);
3149*8975f5c5SAndroid Build Coastguard Worker return false;
3150*8975f5c5SAndroid Build Coastguard Worker }
3151*8975f5c5SAndroid Build Coastguard Worker break;
3152*8975f5c5SAndroid Build Coastguard Worker }
3153*8975f5c5SAndroid Build Coastguard Worker
3154*8975f5c5SAndroid Build Coastguard Worker case GL_PRIMITIVE_BOUNDING_BOX:
3155*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().primitiveBoundingBoxAny())
3156*8975f5c5SAndroid Build Coastguard Worker {
3157*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
3158*8975f5c5SAndroid Build Coastguard Worker return false;
3159*8975f5c5SAndroid Build Coastguard Worker }
3160*8975f5c5SAndroid Build Coastguard Worker break;
3161*8975f5c5SAndroid Build Coastguard Worker
3162*8975f5c5SAndroid Build Coastguard Worker case GL_SHADING_RATE_QCOM:
3163*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().shadingRateQCOM)
3164*8975f5c5SAndroid Build Coastguard Worker {
3165*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
3166*8975f5c5SAndroid Build Coastguard Worker return false;
3167*8975f5c5SAndroid Build Coastguard Worker }
3168*8975f5c5SAndroid Build Coastguard Worker break;
3169*8975f5c5SAndroid Build Coastguard Worker
3170*8975f5c5SAndroid Build Coastguard Worker case GL_MULTISAMPLE_LINE_WIDTH_RANGE:
3171*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 2))
3172*8975f5c5SAndroid Build Coastguard Worker {
3173*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3174*8975f5c5SAndroid Build Coastguard Worker return false;
3175*8975f5c5SAndroid Build Coastguard Worker }
3176*8975f5c5SAndroid Build Coastguard Worker break;
3177*8975f5c5SAndroid Build Coastguard Worker
3178*8975f5c5SAndroid Build Coastguard Worker case GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY:
3179*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 2))
3180*8975f5c5SAndroid Build Coastguard Worker {
3181*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3182*8975f5c5SAndroid Build Coastguard Worker return false;
3183*8975f5c5SAndroid Build Coastguard Worker }
3184*8975f5c5SAndroid Build Coastguard Worker break;
3185*8975f5c5SAndroid Build Coastguard Worker
3186*8975f5c5SAndroid Build Coastguard Worker case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
3187*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 2) &&
3188*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().tessellationShaderAny())
3189*8975f5c5SAndroid Build Coastguard Worker {
3190*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3191*8975f5c5SAndroid Build Coastguard Worker return false;
3192*8975f5c5SAndroid Build Coastguard Worker }
3193*8975f5c5SAndroid Build Coastguard Worker break;
3194*8975f5c5SAndroid Build Coastguard Worker
3195*8975f5c5SAndroid Build Coastguard Worker default:
3196*8975f5c5SAndroid Build Coastguard Worker break;
3197*8975f5c5SAndroid Build Coastguard Worker }
3198*8975f5c5SAndroid Build Coastguard Worker
3199*8975f5c5SAndroid Build Coastguard Worker // pname is valid, but there are no parameters to return
3200*8975f5c5SAndroid Build Coastguard Worker if (*numParams == 0)
3201*8975f5c5SAndroid Build Coastguard Worker {
3202*8975f5c5SAndroid Build Coastguard Worker return false;
3203*8975f5c5SAndroid Build Coastguard Worker }
3204*8975f5c5SAndroid Build Coastguard Worker
3205*8975f5c5SAndroid Build Coastguard Worker return true;
3206*8975f5c5SAndroid Build Coastguard Worker }
3207*8975f5c5SAndroid Build Coastguard Worker
ValidateGetBooleanvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLboolean * params)3208*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBooleanvRobustANGLE(const Context *context,
3209*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3210*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
3211*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
3212*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
3213*8975f5c5SAndroid Build Coastguard Worker const GLboolean *params)
3214*8975f5c5SAndroid Build Coastguard Worker {
3215*8975f5c5SAndroid Build Coastguard Worker GLenum nativeType;
3216*8975f5c5SAndroid Build Coastguard Worker unsigned int numParams = 0;
3217*8975f5c5SAndroid Build Coastguard Worker
3218*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3219*8975f5c5SAndroid Build Coastguard Worker {
3220*8975f5c5SAndroid Build Coastguard Worker return false;
3221*8975f5c5SAndroid Build Coastguard Worker }
3222*8975f5c5SAndroid Build Coastguard Worker
3223*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
3224*8975f5c5SAndroid Build Coastguard Worker
3225*8975f5c5SAndroid Build Coastguard Worker return true;
3226*8975f5c5SAndroid Build Coastguard Worker }
3227*8975f5c5SAndroid Build Coastguard Worker
ValidateGetFloatvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)3228*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFloatvRobustANGLE(const Context *context,
3229*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3230*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
3231*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
3232*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
3233*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
3234*8975f5c5SAndroid Build Coastguard Worker {
3235*8975f5c5SAndroid Build Coastguard Worker GLenum nativeType;
3236*8975f5c5SAndroid Build Coastguard Worker unsigned int numParams = 0;
3237*8975f5c5SAndroid Build Coastguard Worker
3238*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3239*8975f5c5SAndroid Build Coastguard Worker {
3240*8975f5c5SAndroid Build Coastguard Worker return false;
3241*8975f5c5SAndroid Build Coastguard Worker }
3242*8975f5c5SAndroid Build Coastguard Worker
3243*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
3244*8975f5c5SAndroid Build Coastguard Worker
3245*8975f5c5SAndroid Build Coastguard Worker return true;
3246*8975f5c5SAndroid Build Coastguard Worker }
3247*8975f5c5SAndroid Build Coastguard Worker
ValidateGetIntegervRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * data)3248*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetIntegervRobustANGLE(const Context *context,
3249*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3250*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
3251*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
3252*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
3253*8975f5c5SAndroid Build Coastguard Worker const GLint *data)
3254*8975f5c5SAndroid Build Coastguard Worker {
3255*8975f5c5SAndroid Build Coastguard Worker GLenum nativeType;
3256*8975f5c5SAndroid Build Coastguard Worker unsigned int numParams = 0;
3257*8975f5c5SAndroid Build Coastguard Worker
3258*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3259*8975f5c5SAndroid Build Coastguard Worker {
3260*8975f5c5SAndroid Build Coastguard Worker return false;
3261*8975f5c5SAndroid Build Coastguard Worker }
3262*8975f5c5SAndroid Build Coastguard Worker
3263*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
3264*8975f5c5SAndroid Build Coastguard Worker
3265*8975f5c5SAndroid Build Coastguard Worker return true;
3266*8975f5c5SAndroid Build Coastguard Worker }
3267*8975f5c5SAndroid Build Coastguard Worker
ValidateGetInteger64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,GLint64 * data)3268*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetInteger64vRobustANGLE(const Context *context,
3269*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3270*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
3271*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
3272*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
3273*8975f5c5SAndroid Build Coastguard Worker GLint64 *data)
3274*8975f5c5SAndroid Build Coastguard Worker {
3275*8975f5c5SAndroid Build Coastguard Worker GLenum nativeType;
3276*8975f5c5SAndroid Build Coastguard Worker unsigned int numParams = 0;
3277*8975f5c5SAndroid Build Coastguard Worker
3278*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3279*8975f5c5SAndroid Build Coastguard Worker {
3280*8975f5c5SAndroid Build Coastguard Worker return false;
3281*8975f5c5SAndroid Build Coastguard Worker }
3282*8975f5c5SAndroid Build Coastguard Worker
3283*8975f5c5SAndroid Build Coastguard Worker if (nativeType == GL_INT_64_ANGLEX)
3284*8975f5c5SAndroid Build Coastguard Worker {
3285*8975f5c5SAndroid Build Coastguard Worker CastStateValues(context, nativeType, pname, numParams, data);
3286*8975f5c5SAndroid Build Coastguard Worker return false;
3287*8975f5c5SAndroid Build Coastguard Worker }
3288*8975f5c5SAndroid Build Coastguard Worker
3289*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
3290*8975f5c5SAndroid Build Coastguard Worker return true;
3291*8975f5c5SAndroid Build Coastguard Worker }
3292*8975f5c5SAndroid Build Coastguard Worker
ValidateRobustStateQuery(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,GLenum * nativeType,unsigned int * numParams)3293*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustStateQuery(const Context *context,
3294*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3295*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
3296*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
3297*8975f5c5SAndroid Build Coastguard Worker GLenum *nativeType,
3298*8975f5c5SAndroid Build Coastguard Worker unsigned int *numParams)
3299*8975f5c5SAndroid Build Coastguard Worker {
3300*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
3301*8975f5c5SAndroid Build Coastguard Worker {
3302*8975f5c5SAndroid Build Coastguard Worker return false;
3303*8975f5c5SAndroid Build Coastguard Worker }
3304*8975f5c5SAndroid Build Coastguard Worker
3305*8975f5c5SAndroid Build Coastguard Worker if (!ValidateStateQuery(context, entryPoint, pname, nativeType, numParams))
3306*8975f5c5SAndroid Build Coastguard Worker {
3307*8975f5c5SAndroid Build Coastguard Worker return false;
3308*8975f5c5SAndroid Build Coastguard Worker }
3309*8975f5c5SAndroid Build Coastguard Worker
3310*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, *numParams))
3311*8975f5c5SAndroid Build Coastguard Worker {
3312*8975f5c5SAndroid Build Coastguard Worker return false;
3313*8975f5c5SAndroid Build Coastguard Worker }
3314*8975f5c5SAndroid Build Coastguard Worker
3315*8975f5c5SAndroid Build Coastguard Worker return true;
3316*8975f5c5SAndroid Build Coastguard Worker }
3317*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyImageSubDataTarget(const Context * context,angle::EntryPoint entryPoint,GLuint name,GLenum target)3318*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataTarget(const Context *context,
3319*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3320*8975f5c5SAndroid Build Coastguard Worker GLuint name,
3321*8975f5c5SAndroid Build Coastguard Worker GLenum target)
3322*8975f5c5SAndroid Build Coastguard Worker {
3323*8975f5c5SAndroid Build Coastguard Worker // From EXT_copy_image: INVALID_ENUM is generated if either <srcTarget> or <dstTarget> is not
3324*8975f5c5SAndroid Build Coastguard Worker // RENDERBUFFER or a valid non - proxy texture target, is TEXTURE_BUFFER, or is one of the
3325*8975f5c5SAndroid Build Coastguard Worker // cubemap face selectors described in table 3.17, or if the target does not match the type of
3326*8975f5c5SAndroid Build Coastguard Worker // the object. INVALID_VALUE is generated if either <srcName> or <dstName> does not correspond
3327*8975f5c5SAndroid Build Coastguard Worker // to a valid renderbuffer or texture object according to the corresponding target parameter.
3328*8975f5c5SAndroid Build Coastguard Worker switch (target)
3329*8975f5c5SAndroid Build Coastguard Worker {
3330*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
3331*8975f5c5SAndroid Build Coastguard Worker {
3332*8975f5c5SAndroid Build Coastguard Worker RenderbufferID renderbuffer = PackParam<RenderbufferID>(name);
3333*8975f5c5SAndroid Build Coastguard Worker if (!context->isRenderbuffer(renderbuffer))
3334*8975f5c5SAndroid Build Coastguard Worker {
3335*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidRenderbufferName);
3336*8975f5c5SAndroid Build Coastguard Worker return false;
3337*8975f5c5SAndroid Build Coastguard Worker }
3338*8975f5c5SAndroid Build Coastguard Worker break;
3339*8975f5c5SAndroid Build Coastguard Worker }
3340*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
3341*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
3342*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
3343*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
3344*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
3345*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_EXTERNAL_OES:
3346*8975f5c5SAndroid Build Coastguard Worker {
3347*8975f5c5SAndroid Build Coastguard Worker TextureID texture = PackParam<TextureID>(name);
3348*8975f5c5SAndroid Build Coastguard Worker if (!context->isTexture(texture))
3349*8975f5c5SAndroid Build Coastguard Worker {
3350*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
3351*8975f5c5SAndroid Build Coastguard Worker return false;
3352*8975f5c5SAndroid Build Coastguard Worker }
3353*8975f5c5SAndroid Build Coastguard Worker
3354*8975f5c5SAndroid Build Coastguard Worker Texture *textureObject = context->getTexture(texture);
3355*8975f5c5SAndroid Build Coastguard Worker if (textureObject && textureObject->getType() != PackParam<TextureType>(target))
3356*8975f5c5SAndroid Build Coastguard Worker {
3357*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kTextureTypeMismatch);
3358*8975f5c5SAndroid Build Coastguard Worker return false;
3359*8975f5c5SAndroid Build Coastguard Worker }
3360*8975f5c5SAndroid Build Coastguard Worker break;
3361*8975f5c5SAndroid Build Coastguard Worker }
3362*8975f5c5SAndroid Build Coastguard Worker default:
3363*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
3364*8975f5c5SAndroid Build Coastguard Worker return false;
3365*8975f5c5SAndroid Build Coastguard Worker }
3366*8975f5c5SAndroid Build Coastguard Worker
3367*8975f5c5SAndroid Build Coastguard Worker return true;
3368*8975f5c5SAndroid Build Coastguard Worker }
3369*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyImageSubDataLevel(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLint level)3370*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataLevel(const Context *context,
3371*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3372*8975f5c5SAndroid Build Coastguard Worker GLenum target,
3373*8975f5c5SAndroid Build Coastguard Worker GLint level)
3374*8975f5c5SAndroid Build Coastguard Worker {
3375*8975f5c5SAndroid Build Coastguard Worker switch (target)
3376*8975f5c5SAndroid Build Coastguard Worker {
3377*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
3378*8975f5c5SAndroid Build Coastguard Worker {
3379*8975f5c5SAndroid Build Coastguard Worker if (level != 0)
3380*8975f5c5SAndroid Build Coastguard Worker {
3381*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3382*8975f5c5SAndroid Build Coastguard Worker return false;
3383*8975f5c5SAndroid Build Coastguard Worker }
3384*8975f5c5SAndroid Build Coastguard Worker break;
3385*8975f5c5SAndroid Build Coastguard Worker }
3386*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
3387*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
3388*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
3389*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
3390*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
3391*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_EXTERNAL_OES:
3392*8975f5c5SAndroid Build Coastguard Worker {
3393*8975f5c5SAndroid Build Coastguard Worker if (!ValidMipLevel(context, PackParam<TextureType>(target), level))
3394*8975f5c5SAndroid Build Coastguard Worker {
3395*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3396*8975f5c5SAndroid Build Coastguard Worker return false;
3397*8975f5c5SAndroid Build Coastguard Worker }
3398*8975f5c5SAndroid Build Coastguard Worker break;
3399*8975f5c5SAndroid Build Coastguard Worker }
3400*8975f5c5SAndroid Build Coastguard Worker default:
3401*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
3402*8975f5c5SAndroid Build Coastguard Worker return false;
3403*8975f5c5SAndroid Build Coastguard Worker }
3404*8975f5c5SAndroid Build Coastguard Worker
3405*8975f5c5SAndroid Build Coastguard Worker return true;
3406*8975f5c5SAndroid Build Coastguard Worker }
3407*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyImageSubDataTargetRegion(const Context * context,angle::EntryPoint entryPoint,GLuint name,GLenum target,GLint level,GLint offsetX,GLint offsetY,GLint offsetZ,GLsizei width,GLsizei height,GLsizei * samples)3408*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataTargetRegion(const Context *context,
3409*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3410*8975f5c5SAndroid Build Coastguard Worker GLuint name,
3411*8975f5c5SAndroid Build Coastguard Worker GLenum target,
3412*8975f5c5SAndroid Build Coastguard Worker GLint level,
3413*8975f5c5SAndroid Build Coastguard Worker GLint offsetX,
3414*8975f5c5SAndroid Build Coastguard Worker GLint offsetY,
3415*8975f5c5SAndroid Build Coastguard Worker GLint offsetZ,
3416*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
3417*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
3418*8975f5c5SAndroid Build Coastguard Worker GLsizei *samples)
3419*8975f5c5SAndroid Build Coastguard Worker {
3420*8975f5c5SAndroid Build Coastguard Worker // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries
3421*8975f5c5SAndroid Build Coastguard Worker // of the corresponding image object.
3422*8975f5c5SAndroid Build Coastguard Worker if (offsetX < 0 || offsetY < 0 || offsetZ < 0)
3423*8975f5c5SAndroid Build Coastguard Worker {
3424*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3425*8975f5c5SAndroid Build Coastguard Worker return false;
3426*8975f5c5SAndroid Build Coastguard Worker }
3427*8975f5c5SAndroid Build Coastguard Worker
3428*8975f5c5SAndroid Build Coastguard Worker if (target == GL_RENDERBUFFER)
3429*8975f5c5SAndroid Build Coastguard Worker {
3430*8975f5c5SAndroid Build Coastguard Worker // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the
3431*8975f5c5SAndroid Build Coastguard Worker // boundaries of the corresponding image object
3432*8975f5c5SAndroid Build Coastguard Worker Renderbuffer *buffer = context->getRenderbuffer(PackParam<RenderbufferID>(name));
3433*8975f5c5SAndroid Build Coastguard Worker if ((buffer->getWidth() - offsetX < width) || (buffer->getHeight() - offsetY < height))
3434*8975f5c5SAndroid Build Coastguard Worker {
3435*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureTooSmall);
3436*8975f5c5SAndroid Build Coastguard Worker return false;
3437*8975f5c5SAndroid Build Coastguard Worker }
3438*8975f5c5SAndroid Build Coastguard Worker }
3439*8975f5c5SAndroid Build Coastguard Worker else
3440*8975f5c5SAndroid Build Coastguard Worker {
3441*8975f5c5SAndroid Build Coastguard Worker Texture *texture = context->getTexture(PackParam<TextureID>(name));
3442*8975f5c5SAndroid Build Coastguard Worker
3443*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if either object is a texture and the texture is not
3444*8975f5c5SAndroid Build Coastguard Worker // complete
3445*8975f5c5SAndroid Build Coastguard Worker // This will handle the texture completeness check. Note that this ignores format-based
3446*8975f5c5SAndroid Build Coastguard Worker // compleness rules.
3447*8975f5c5SAndroid Build Coastguard Worker if (!texture->isSamplerCompleteForCopyImage(context, nullptr))
3448*8975f5c5SAndroid Build Coastguard Worker {
3449*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNotTextureComplete);
3450*8975f5c5SAndroid Build Coastguard Worker return false;
3451*8975f5c5SAndroid Build Coastguard Worker }
3452*8975f5c5SAndroid Build Coastguard Worker
3453*8975f5c5SAndroid Build Coastguard Worker GLenum textureTargetToUse = target;
3454*8975f5c5SAndroid Build Coastguard Worker if (target == GL_TEXTURE_CUBE_MAP)
3455*8975f5c5SAndroid Build Coastguard Worker {
3456*8975f5c5SAndroid Build Coastguard Worker // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the textureWidth/textureHeight
3457*8975f5c5SAndroid Build Coastguard Worker textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
3458*8975f5c5SAndroid Build Coastguard Worker }
3459*8975f5c5SAndroid Build Coastguard Worker
3460*8975f5c5SAndroid Build Coastguard Worker const GLsizei textureWidth = static_cast<GLsizei>(
3461*8975f5c5SAndroid Build Coastguard Worker texture->getWidth(PackParam<TextureTarget>(textureTargetToUse), level));
3462*8975f5c5SAndroid Build Coastguard Worker const GLsizei textureHeight = static_cast<GLsizei>(
3463*8975f5c5SAndroid Build Coastguard Worker texture->getHeight(PackParam<TextureTarget>(textureTargetToUse), level));
3464*8975f5c5SAndroid Build Coastguard Worker
3465*8975f5c5SAndroid Build Coastguard Worker // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the
3466*8975f5c5SAndroid Build Coastguard Worker // boundaries of the corresponding image object
3467*8975f5c5SAndroid Build Coastguard Worker if ((textureWidth - offsetX < width) || (textureHeight - offsetY < height))
3468*8975f5c5SAndroid Build Coastguard Worker {
3469*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureTooSmall);
3470*8975f5c5SAndroid Build Coastguard Worker return false;
3471*8975f5c5SAndroid Build Coastguard Worker }
3472*8975f5c5SAndroid Build Coastguard Worker
3473*8975f5c5SAndroid Build Coastguard Worker *samples = texture->getSamples(PackParam<TextureTarget>(textureTargetToUse), level);
3474*8975f5c5SAndroid Build Coastguard Worker *samples = (*samples == 0) ? 1 : *samples;
3475*8975f5c5SAndroid Build Coastguard Worker }
3476*8975f5c5SAndroid Build Coastguard Worker
3477*8975f5c5SAndroid Build Coastguard Worker return true;
3478*8975f5c5SAndroid Build Coastguard Worker }
3479*8975f5c5SAndroid Build Coastguard Worker
ValidateCompressedRegion(const Context * context,angle::EntryPoint entryPoint,const InternalFormat & formatInfo,GLsizei width,GLsizei height)3480*8975f5c5SAndroid Build Coastguard Worker bool ValidateCompressedRegion(const Context *context,
3481*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3482*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo,
3483*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
3484*8975f5c5SAndroid Build Coastguard Worker GLsizei height)
3485*8975f5c5SAndroid Build Coastguard Worker {
3486*8975f5c5SAndroid Build Coastguard Worker ASSERT(formatInfo.compressed);
3487*8975f5c5SAndroid Build Coastguard Worker
3488*8975f5c5SAndroid Build Coastguard Worker // INVALID_VALUE is generated if the image format is compressed and the dimensions of the
3489*8975f5c5SAndroid Build Coastguard Worker // subregion fail to meet the alignment constraints of the format.
3490*8975f5c5SAndroid Build Coastguard Worker if ((width % formatInfo.compressedBlockWidth != 0) ||
3491*8975f5c5SAndroid Build Coastguard Worker (height % formatInfo.compressedBlockHeight != 0))
3492*8975f5c5SAndroid Build Coastguard Worker {
3493*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidCompressedRegionSize);
3494*8975f5c5SAndroid Build Coastguard Worker return false;
3495*8975f5c5SAndroid Build Coastguard Worker }
3496*8975f5c5SAndroid Build Coastguard Worker
3497*8975f5c5SAndroid Build Coastguard Worker return true;
3498*8975f5c5SAndroid Build Coastguard Worker }
3499*8975f5c5SAndroid Build Coastguard Worker
GetTargetFormatInfo(const Context * context,angle::EntryPoint entryPoint,GLuint name,GLenum target,GLint level)3500*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &GetTargetFormatInfo(const Context *context,
3501*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3502*8975f5c5SAndroid Build Coastguard Worker GLuint name,
3503*8975f5c5SAndroid Build Coastguard Worker GLenum target,
3504*8975f5c5SAndroid Build Coastguard Worker GLint level)
3505*8975f5c5SAndroid Build Coastguard Worker {
3506*8975f5c5SAndroid Build Coastguard Worker static const InternalFormat defaultInternalFormat;
3507*8975f5c5SAndroid Build Coastguard Worker
3508*8975f5c5SAndroid Build Coastguard Worker switch (target)
3509*8975f5c5SAndroid Build Coastguard Worker {
3510*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
3511*8975f5c5SAndroid Build Coastguard Worker {
3512*8975f5c5SAndroid Build Coastguard Worker Renderbuffer *buffer = context->getRenderbuffer(PackParam<RenderbufferID>(name));
3513*8975f5c5SAndroid Build Coastguard Worker return *buffer->getFormat().info;
3514*8975f5c5SAndroid Build Coastguard Worker }
3515*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
3516*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
3517*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
3518*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
3519*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
3520*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_EXTERNAL_OES:
3521*8975f5c5SAndroid Build Coastguard Worker {
3522*8975f5c5SAndroid Build Coastguard Worker Texture *texture = context->getTexture(PackParam<TextureID>(name));
3523*8975f5c5SAndroid Build Coastguard Worker GLenum textureTargetToUse = target;
3524*8975f5c5SAndroid Build Coastguard Worker
3525*8975f5c5SAndroid Build Coastguard Worker if (target == GL_TEXTURE_CUBE_MAP)
3526*8975f5c5SAndroid Build Coastguard Worker {
3527*8975f5c5SAndroid Build Coastguard Worker // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the
3528*8975f5c5SAndroid Build Coastguard Worker // textureWidth/textureHeight
3529*8975f5c5SAndroid Build Coastguard Worker textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
3530*8975f5c5SAndroid Build Coastguard Worker }
3531*8975f5c5SAndroid Build Coastguard Worker return *texture->getFormat(PackParam<TextureTarget>(textureTargetToUse), level).info;
3532*8975f5c5SAndroid Build Coastguard Worker }
3533*8975f5c5SAndroid Build Coastguard Worker default:
3534*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
3535*8975f5c5SAndroid Build Coastguard Worker return defaultInternalFormat;
3536*8975f5c5SAndroid Build Coastguard Worker }
3537*8975f5c5SAndroid Build Coastguard Worker }
3538*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyMixedFormatCompatible(GLenum uncompressedFormat,GLenum compressedFormat)3539*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyMixedFormatCompatible(GLenum uncompressedFormat, GLenum compressedFormat)
3540*8975f5c5SAndroid Build Coastguard Worker {
3541*8975f5c5SAndroid Build Coastguard Worker // Validates mixed format compatibility (uncompressed and compressed) from Table 4.X.1 of the
3542*8975f5c5SAndroid Build Coastguard Worker // EXT_copy_image spec.
3543*8975f5c5SAndroid Build Coastguard Worker switch (compressedFormat)
3544*8975f5c5SAndroid Build Coastguard Worker {
3545*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
3546*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
3547*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
3548*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
3549*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
3550*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
3551*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
3552*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
3553*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
3554*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
3555*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA8_ETC2_EAC:
3556*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
3557*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RG11_EAC:
3558*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RG11_EAC:
3559*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
3560*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
3561*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
3562*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
3563*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
3564*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
3565*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
3566*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
3567*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
3568*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
3569*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
3570*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
3571*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
3572*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
3573*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
3574*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
3575*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
3576*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
3577*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
3578*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
3579*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
3580*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
3581*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
3582*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
3583*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
3584*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
3585*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
3586*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
3587*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
3588*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
3589*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
3590*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
3591*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
3592*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
3593*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
3594*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
3595*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
3596*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
3597*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
3598*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
3599*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
3600*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
3601*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
3602*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
3603*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
3604*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
3605*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
3606*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:
3607*8975f5c5SAndroid Build Coastguard Worker {
3608*8975f5c5SAndroid Build Coastguard Worker switch (uncompressedFormat)
3609*8975f5c5SAndroid Build Coastguard Worker {
3610*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA32UI:
3611*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA32I:
3612*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA32F:
3613*8975f5c5SAndroid Build Coastguard Worker return true;
3614*8975f5c5SAndroid Build Coastguard Worker default:
3615*8975f5c5SAndroid Build Coastguard Worker return false;
3616*8975f5c5SAndroid Build Coastguard Worker }
3617*8975f5c5SAndroid Build Coastguard Worker }
3618*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
3619*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
3620*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
3621*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
3622*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_RGTC1_EXT:
3623*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
3624*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_ETC2:
3625*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_ETC2:
3626*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_R11_EAC:
3627*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_R11_EAC:
3628*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
3629*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
3630*8975f5c5SAndroid Build Coastguard Worker {
3631*8975f5c5SAndroid Build Coastguard Worker switch (uncompressedFormat)
3632*8975f5c5SAndroid Build Coastguard Worker {
3633*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA16UI:
3634*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA16I:
3635*8975f5c5SAndroid Build Coastguard Worker case GL_RGBA16F:
3636*8975f5c5SAndroid Build Coastguard Worker case GL_RG32UI:
3637*8975f5c5SAndroid Build Coastguard Worker case GL_RG32I:
3638*8975f5c5SAndroid Build Coastguard Worker case GL_RG32F:
3639*8975f5c5SAndroid Build Coastguard Worker return true;
3640*8975f5c5SAndroid Build Coastguard Worker default:
3641*8975f5c5SAndroid Build Coastguard Worker return false;
3642*8975f5c5SAndroid Build Coastguard Worker }
3643*8975f5c5SAndroid Build Coastguard Worker }
3644*8975f5c5SAndroid Build Coastguard Worker default:
3645*8975f5c5SAndroid Build Coastguard Worker break;
3646*8975f5c5SAndroid Build Coastguard Worker }
3647*8975f5c5SAndroid Build Coastguard Worker
3648*8975f5c5SAndroid Build Coastguard Worker return false;
3649*8975f5c5SAndroid Build Coastguard Worker }
3650*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyCompressedFormatCompatible(const InternalFormat & srcFormatInfo,const InternalFormat & dstFormatInfo)3651*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyCompressedFormatCompatible(const InternalFormat &srcFormatInfo,
3652*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &dstFormatInfo)
3653*8975f5c5SAndroid Build Coastguard Worker {
3654*8975f5c5SAndroid Build Coastguard Worker // Validates compressed format compatibility from Table 4.X.2 of the EXT_copy_image spec.
3655*8975f5c5SAndroid Build Coastguard Worker
3656*8975f5c5SAndroid Build Coastguard Worker ASSERT(srcFormatInfo.internalFormat != dstFormatInfo.internalFormat);
3657*8975f5c5SAndroid Build Coastguard Worker
3658*8975f5c5SAndroid Build Coastguard Worker const GLenum srcFormat = srcFormatInfo.internalFormat;
3659*8975f5c5SAndroid Build Coastguard Worker const GLenum dstFormat = dstFormatInfo.internalFormat;
3660*8975f5c5SAndroid Build Coastguard Worker
3661*8975f5c5SAndroid Build Coastguard Worker switch (srcFormat)
3662*8975f5c5SAndroid Build Coastguard Worker {
3663*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_RGTC1_EXT:
3664*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_SIGNED_RED_RGTC1_EXT);
3665*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
3666*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_RED_RGTC1_EXT);
3667*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
3668*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT);
3669*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
3670*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT);
3671*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
3672*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT);
3673*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
3674*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT);
3675*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_R11_EAC:
3676*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_SIGNED_R11_EAC);
3677*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_R11_EAC:
3678*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_R11_EAC);
3679*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RG11_EAC:
3680*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_SIGNED_RG11_EAC);
3681*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_SIGNED_RG11_EAC:
3682*8975f5c5SAndroid Build Coastguard Worker return (dstFormat == GL_COMPRESSED_RG11_EAC);
3683*8975f5c5SAndroid Build Coastguard Worker default:
3684*8975f5c5SAndroid Build Coastguard Worker break;
3685*8975f5c5SAndroid Build Coastguard Worker }
3686*8975f5c5SAndroid Build Coastguard Worker
3687*8975f5c5SAndroid Build Coastguard Worker // Since they can't be the same format and are both compressed formats, one must be linear and
3688*8975f5c5SAndroid Build Coastguard Worker // the other nonlinear.
3689*8975f5c5SAndroid Build Coastguard Worker if (srcFormatInfo.colorEncoding == dstFormatInfo.colorEncoding)
3690*8975f5c5SAndroid Build Coastguard Worker {
3691*8975f5c5SAndroid Build Coastguard Worker return false;
3692*8975f5c5SAndroid Build Coastguard Worker }
3693*8975f5c5SAndroid Build Coastguard Worker
3694*8975f5c5SAndroid Build Coastguard Worker const GLenum linearFormat = (srcFormatInfo.colorEncoding == GL_LINEAR) ? srcFormat : dstFormat;
3695*8975f5c5SAndroid Build Coastguard Worker const GLenum nonLinearFormat =
3696*8975f5c5SAndroid Build Coastguard Worker (srcFormatInfo.colorEncoding != GL_LINEAR) ? srcFormat : dstFormat;
3697*8975f5c5SAndroid Build Coastguard Worker
3698*8975f5c5SAndroid Build Coastguard Worker switch (linearFormat)
3699*8975f5c5SAndroid Build Coastguard Worker {
3700*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
3701*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT);
3702*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
3703*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
3704*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
3705*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
3706*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
3707*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
3708*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
3709*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
3710*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_ETC2:
3711*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ETC2);
3712*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
3713*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
3714*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA8_ETC2_EAC:
3715*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
3716*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
3717*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
3718*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
3719*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR);
3720*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
3721*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR);
3722*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
3723*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR);
3724*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
3725*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR);
3726*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
3727*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR);
3728*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
3729*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR);
3730*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
3731*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR);
3732*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
3733*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR);
3734*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
3735*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR);
3736*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
3737*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR);
3738*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
3739*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR);
3740*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
3741*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR);
3742*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
3743*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR);
3744*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
3745*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES);
3746*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
3747*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES);
3748*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
3749*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES);
3750*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
3751*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES);
3752*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
3753*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES);
3754*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
3755*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES);
3756*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
3757*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES);
3758*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
3759*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES);
3760*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
3761*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES);
3762*8975f5c5SAndroid Build Coastguard Worker case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
3763*8975f5c5SAndroid Build Coastguard Worker return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES);
3764*8975f5c5SAndroid Build Coastguard Worker default:
3765*8975f5c5SAndroid Build Coastguard Worker break;
3766*8975f5c5SAndroid Build Coastguard Worker }
3767*8975f5c5SAndroid Build Coastguard Worker
3768*8975f5c5SAndroid Build Coastguard Worker return false;
3769*8975f5c5SAndroid Build Coastguard Worker }
3770*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyFormatCompatible(const InternalFormat & srcFormatInfo,const InternalFormat & dstFormatInfo)3771*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyFormatCompatible(const InternalFormat &srcFormatInfo,
3772*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &dstFormatInfo)
3773*8975f5c5SAndroid Build Coastguard Worker {
3774*8975f5c5SAndroid Build Coastguard Worker // Matching source and destination formats are compatible.
3775*8975f5c5SAndroid Build Coastguard Worker if (srcFormatInfo.internalFormat == dstFormatInfo.internalFormat)
3776*8975f5c5SAndroid Build Coastguard Worker {
3777*8975f5c5SAndroid Build Coastguard Worker return true;
3778*8975f5c5SAndroid Build Coastguard Worker }
3779*8975f5c5SAndroid Build Coastguard Worker
3780*8975f5c5SAndroid Build Coastguard Worker if (srcFormatInfo.compressed != dstFormatInfo.compressed)
3781*8975f5c5SAndroid Build Coastguard Worker {
3782*8975f5c5SAndroid Build Coastguard Worker GLenum uncompressedFormat = (!srcFormatInfo.compressed) ? srcFormatInfo.internalFormat
3783*8975f5c5SAndroid Build Coastguard Worker : dstFormatInfo.internalFormat;
3784*8975f5c5SAndroid Build Coastguard Worker GLenum compressedFormat = (srcFormatInfo.compressed) ? srcFormatInfo.internalFormat
3785*8975f5c5SAndroid Build Coastguard Worker : dstFormatInfo.internalFormat;
3786*8975f5c5SAndroid Build Coastguard Worker
3787*8975f5c5SAndroid Build Coastguard Worker return ValidateCopyMixedFormatCompatible(uncompressedFormat, compressedFormat);
3788*8975f5c5SAndroid Build Coastguard Worker }
3789*8975f5c5SAndroid Build Coastguard Worker
3790*8975f5c5SAndroid Build Coastguard Worker if (!srcFormatInfo.compressed)
3791*8975f5c5SAndroid Build Coastguard Worker {
3792*8975f5c5SAndroid Build Coastguard Worker // Source and destination are uncompressed formats.
3793*8975f5c5SAndroid Build Coastguard Worker return (srcFormatInfo.pixelBytes == dstFormatInfo.pixelBytes);
3794*8975f5c5SAndroid Build Coastguard Worker }
3795*8975f5c5SAndroid Build Coastguard Worker
3796*8975f5c5SAndroid Build Coastguard Worker return ValidateCopyCompressedFormatCompatible(srcFormatInfo, dstFormatInfo);
3797*8975f5c5SAndroid Build Coastguard Worker }
3798*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyImageSubDataBase(const Context * context,angle::EntryPoint entryPoint,GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)3799*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataBase(const Context *context,
3800*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3801*8975f5c5SAndroid Build Coastguard Worker GLuint srcName,
3802*8975f5c5SAndroid Build Coastguard Worker GLenum srcTarget,
3803*8975f5c5SAndroid Build Coastguard Worker GLint srcLevel,
3804*8975f5c5SAndroid Build Coastguard Worker GLint srcX,
3805*8975f5c5SAndroid Build Coastguard Worker GLint srcY,
3806*8975f5c5SAndroid Build Coastguard Worker GLint srcZ,
3807*8975f5c5SAndroid Build Coastguard Worker GLuint dstName,
3808*8975f5c5SAndroid Build Coastguard Worker GLenum dstTarget,
3809*8975f5c5SAndroid Build Coastguard Worker GLint dstLevel,
3810*8975f5c5SAndroid Build Coastguard Worker GLint dstX,
3811*8975f5c5SAndroid Build Coastguard Worker GLint dstY,
3812*8975f5c5SAndroid Build Coastguard Worker GLint dstZ,
3813*8975f5c5SAndroid Build Coastguard Worker GLsizei srcWidth,
3814*8975f5c5SAndroid Build Coastguard Worker GLsizei srcHeight,
3815*8975f5c5SAndroid Build Coastguard Worker GLsizei srcDepth)
3816*8975f5c5SAndroid Build Coastguard Worker {
3817*8975f5c5SAndroid Build Coastguard Worker // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries
3818*8975f5c5SAndroid Build Coastguard Worker // of the corresponding image object
3819*8975f5c5SAndroid Build Coastguard Worker if ((srcWidth < 0) || (srcHeight < 0) || (srcDepth < 0))
3820*8975f5c5SAndroid Build Coastguard Worker {
3821*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3822*8975f5c5SAndroid Build Coastguard Worker return false;
3823*8975f5c5SAndroid Build Coastguard Worker }
3824*8975f5c5SAndroid Build Coastguard Worker
3825*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyImageSubDataTarget(context, entryPoint, srcName, srcTarget))
3826*8975f5c5SAndroid Build Coastguard Worker {
3827*8975f5c5SAndroid Build Coastguard Worker return false;
3828*8975f5c5SAndroid Build Coastguard Worker }
3829*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyImageSubDataTarget(context, entryPoint, dstName, dstTarget))
3830*8975f5c5SAndroid Build Coastguard Worker {
3831*8975f5c5SAndroid Build Coastguard Worker return false;
3832*8975f5c5SAndroid Build Coastguard Worker }
3833*8975f5c5SAndroid Build Coastguard Worker
3834*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyImageSubDataLevel(context, entryPoint, srcTarget, srcLevel))
3835*8975f5c5SAndroid Build Coastguard Worker {
3836*8975f5c5SAndroid Build Coastguard Worker return false;
3837*8975f5c5SAndroid Build Coastguard Worker }
3838*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyImageSubDataLevel(context, entryPoint, dstTarget, dstLevel))
3839*8975f5c5SAndroid Build Coastguard Worker {
3840*8975f5c5SAndroid Build Coastguard Worker return false;
3841*8975f5c5SAndroid Build Coastguard Worker }
3842*8975f5c5SAndroid Build Coastguard Worker
3843*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &srcFormatInfo =
3844*8975f5c5SAndroid Build Coastguard Worker GetTargetFormatInfo(context, entryPoint, srcName, srcTarget, srcLevel);
3845*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &dstFormatInfo =
3846*8975f5c5SAndroid Build Coastguard Worker GetTargetFormatInfo(context, entryPoint, dstName, dstTarget, dstLevel);
3847*8975f5c5SAndroid Build Coastguard Worker GLsizei dstWidth = srcWidth;
3848*8975f5c5SAndroid Build Coastguard Worker GLsizei dstHeight = srcHeight;
3849*8975f5c5SAndroid Build Coastguard Worker GLsizei srcSamples = 1;
3850*8975f5c5SAndroid Build Coastguard Worker GLsizei dstSamples = 1;
3851*8975f5c5SAndroid Build Coastguard Worker
3852*8975f5c5SAndroid Build Coastguard Worker if (srcFormatInfo.internalFormat == GL_NONE || dstFormatInfo.internalFormat == GL_NONE)
3853*8975f5c5SAndroid Build Coastguard Worker {
3854*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureLevel);
3855*8975f5c5SAndroid Build Coastguard Worker return false;
3856*8975f5c5SAndroid Build Coastguard Worker }
3857*8975f5c5SAndroid Build Coastguard Worker
3858*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, srcName, srcTarget, srcLevel,
3859*8975f5c5SAndroid Build Coastguard Worker srcX, srcY, srcZ, srcWidth, srcHeight, &srcSamples))
3860*8975f5c5SAndroid Build Coastguard Worker {
3861*8975f5c5SAndroid Build Coastguard Worker return false;
3862*8975f5c5SAndroid Build Coastguard Worker }
3863*8975f5c5SAndroid Build Coastguard Worker
3864*8975f5c5SAndroid Build Coastguard Worker // When copying from a compressed image to an uncompressed image the image texel dimensions
3865*8975f5c5SAndroid Build Coastguard Worker // written to the uncompressed image will be source extent divided by the compressed texel block
3866*8975f5c5SAndroid Build Coastguard Worker // dimensions.
3867*8975f5c5SAndroid Build Coastguard Worker if ((srcFormatInfo.compressed) && (!dstFormatInfo.compressed))
3868*8975f5c5SAndroid Build Coastguard Worker {
3869*8975f5c5SAndroid Build Coastguard Worker ASSERT(srcFormatInfo.compressedBlockWidth != 0);
3870*8975f5c5SAndroid Build Coastguard Worker ASSERT(srcFormatInfo.compressedBlockHeight != 0);
3871*8975f5c5SAndroid Build Coastguard Worker
3872*8975f5c5SAndroid Build Coastguard Worker dstWidth /= srcFormatInfo.compressedBlockWidth;
3873*8975f5c5SAndroid Build Coastguard Worker dstHeight /= srcFormatInfo.compressedBlockHeight;
3874*8975f5c5SAndroid Build Coastguard Worker }
3875*8975f5c5SAndroid Build Coastguard Worker // When copying from an uncompressed image to a compressed image the image texel dimensions
3876*8975f5c5SAndroid Build Coastguard Worker // written to the compressed image will be the source extent multiplied by the compressed texel
3877*8975f5c5SAndroid Build Coastguard Worker // block dimensions.
3878*8975f5c5SAndroid Build Coastguard Worker else if ((!srcFormatInfo.compressed) && (dstFormatInfo.compressed))
3879*8975f5c5SAndroid Build Coastguard Worker {
3880*8975f5c5SAndroid Build Coastguard Worker dstWidth *= dstFormatInfo.compressedBlockWidth;
3881*8975f5c5SAndroid Build Coastguard Worker dstHeight *= dstFormatInfo.compressedBlockHeight;
3882*8975f5c5SAndroid Build Coastguard Worker }
3883*8975f5c5SAndroid Build Coastguard Worker
3884*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, dstName, dstTarget, dstLevel,
3885*8975f5c5SAndroid Build Coastguard Worker dstX, dstY, dstZ, dstWidth, dstHeight, &dstSamples))
3886*8975f5c5SAndroid Build Coastguard Worker {
3887*8975f5c5SAndroid Build Coastguard Worker return false;
3888*8975f5c5SAndroid Build Coastguard Worker }
3889*8975f5c5SAndroid Build Coastguard Worker
3890*8975f5c5SAndroid Build Coastguard Worker bool fillsEntireMip = false;
3891*8975f5c5SAndroid Build Coastguard Worker gl::Texture *dstTexture = context->getTexture({dstName});
3892*8975f5c5SAndroid Build Coastguard Worker gl::TextureTarget dstTargetPacked = gl::PackParam<gl::TextureTarget>(dstTarget);
3893*8975f5c5SAndroid Build Coastguard Worker // TODO(http://anglebug.com/42264179): Some targets (e.g., GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER)
3894*8975f5c5SAndroid Build Coastguard Worker // are unsupported when used with compressed formats due to gl::PackParam() returning
3895*8975f5c5SAndroid Build Coastguard Worker // TextureTarget::InvalidEnum.
3896*8975f5c5SAndroid Build Coastguard Worker if (dstTargetPacked != gl::TextureTarget::InvalidEnum)
3897*8975f5c5SAndroid Build Coastguard Worker {
3898*8975f5c5SAndroid Build Coastguard Worker const gl::Extents &dstExtents = dstTexture->getExtents(dstTargetPacked, dstLevel);
3899*8975f5c5SAndroid Build Coastguard Worker fillsEntireMip = dstX == 0 && dstY == 0 && dstZ == 0 && srcWidth == dstExtents.width &&
3900*8975f5c5SAndroid Build Coastguard Worker srcHeight == dstExtents.height && srcDepth == dstExtents.depth;
3901*8975f5c5SAndroid Build Coastguard Worker }
3902*8975f5c5SAndroid Build Coastguard Worker
3903*8975f5c5SAndroid Build Coastguard Worker if (srcFormatInfo.compressed && !fillsEntireMip &&
3904*8975f5c5SAndroid Build Coastguard Worker !ValidateCompressedRegion(context, entryPoint, srcFormatInfo, srcWidth, srcHeight))
3905*8975f5c5SAndroid Build Coastguard Worker {
3906*8975f5c5SAndroid Build Coastguard Worker return false;
3907*8975f5c5SAndroid Build Coastguard Worker }
3908*8975f5c5SAndroid Build Coastguard Worker
3909*8975f5c5SAndroid Build Coastguard Worker if (dstFormatInfo.compressed && !fillsEntireMip &&
3910*8975f5c5SAndroid Build Coastguard Worker !ValidateCompressedRegion(context, entryPoint, dstFormatInfo, dstWidth, dstHeight))
3911*8975f5c5SAndroid Build Coastguard Worker {
3912*8975f5c5SAndroid Build Coastguard Worker return false;
3913*8975f5c5SAndroid Build Coastguard Worker }
3914*8975f5c5SAndroid Build Coastguard Worker
3915*8975f5c5SAndroid Build Coastguard Worker // From EXT_copy_image: INVALID_OPERATION is generated if the source and destination formats
3916*8975f5c5SAndroid Build Coastguard Worker // are not compatible, if one image is compressed and the other is uncompressed and the block
3917*8975f5c5SAndroid Build Coastguard Worker // size of compressed image is not equal to the texel size of the compressed image.
3918*8975f5c5SAndroid Build Coastguard Worker if (!ValidateCopyFormatCompatible(srcFormatInfo, dstFormatInfo))
3919*8975f5c5SAndroid Build Coastguard Worker {
3920*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIncompatibleTextures);
3921*8975f5c5SAndroid Build Coastguard Worker return false;
3922*8975f5c5SAndroid Build Coastguard Worker }
3923*8975f5c5SAndroid Build Coastguard Worker
3924*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if the source and destination number of samples do not match
3925*8975f5c5SAndroid Build Coastguard Worker if (srcSamples != dstSamples)
3926*8975f5c5SAndroid Build Coastguard Worker {
3927*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
3928*8975f5c5SAndroid Build Coastguard Worker return false;
3929*8975f5c5SAndroid Build Coastguard Worker }
3930*8975f5c5SAndroid Build Coastguard Worker
3931*8975f5c5SAndroid Build Coastguard Worker return true;
3932*8975f5c5SAndroid Build Coastguard Worker }
3933*8975f5c5SAndroid Build Coastguard Worker
ValidateCopyTexImageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border,Format * textureFormatOut)3934*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyTexImageParametersBase(const Context *context,
3935*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
3936*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
3937*8975f5c5SAndroid Build Coastguard Worker GLint level,
3938*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
3939*8975f5c5SAndroid Build Coastguard Worker bool isSubImage,
3940*8975f5c5SAndroid Build Coastguard Worker GLint xoffset,
3941*8975f5c5SAndroid Build Coastguard Worker GLint yoffset,
3942*8975f5c5SAndroid Build Coastguard Worker GLint zoffset,
3943*8975f5c5SAndroid Build Coastguard Worker GLint x,
3944*8975f5c5SAndroid Build Coastguard Worker GLint y,
3945*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
3946*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
3947*8975f5c5SAndroid Build Coastguard Worker GLint border,
3948*8975f5c5SAndroid Build Coastguard Worker Format *textureFormatOut)
3949*8975f5c5SAndroid Build Coastguard Worker {
3950*8975f5c5SAndroid Build Coastguard Worker TextureType texType = TextureTargetToType(target);
3951*8975f5c5SAndroid Build Coastguard Worker
3952*8975f5c5SAndroid Build Coastguard Worker if (xoffset < 0 || yoffset < 0 || zoffset < 0)
3953*8975f5c5SAndroid Build Coastguard Worker {
3954*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3955*8975f5c5SAndroid Build Coastguard Worker return false;
3956*8975f5c5SAndroid Build Coastguard Worker }
3957*8975f5c5SAndroid Build Coastguard Worker
3958*8975f5c5SAndroid Build Coastguard Worker if (width < 0 || height < 0)
3959*8975f5c5SAndroid Build Coastguard Worker {
3960*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3961*8975f5c5SAndroid Build Coastguard Worker return false;
3962*8975f5c5SAndroid Build Coastguard Worker }
3963*8975f5c5SAndroid Build Coastguard Worker
3964*8975f5c5SAndroid Build Coastguard Worker if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
3965*8975f5c5SAndroid Build Coastguard Worker std::numeric_limits<GLsizei>::max() - yoffset < height)
3966*8975f5c5SAndroid Build Coastguard Worker {
3967*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
3968*8975f5c5SAndroid Build Coastguard Worker return false;
3969*8975f5c5SAndroid Build Coastguard Worker }
3970*8975f5c5SAndroid Build Coastguard Worker
3971*8975f5c5SAndroid Build Coastguard Worker if (std::numeric_limits<GLint>::max() - width < x ||
3972*8975f5c5SAndroid Build Coastguard Worker std::numeric_limits<GLint>::max() - height < y)
3973*8975f5c5SAndroid Build Coastguard Worker {
3974*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIntegerOverflow);
3975*8975f5c5SAndroid Build Coastguard Worker return false;
3976*8975f5c5SAndroid Build Coastguard Worker }
3977*8975f5c5SAndroid Build Coastguard Worker
3978*8975f5c5SAndroid Build Coastguard Worker if (border != 0)
3979*8975f5c5SAndroid Build Coastguard Worker {
3980*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBorder);
3981*8975f5c5SAndroid Build Coastguard Worker return false;
3982*8975f5c5SAndroid Build Coastguard Worker }
3983*8975f5c5SAndroid Build Coastguard Worker
3984*8975f5c5SAndroid Build Coastguard Worker if (!ValidMipLevel(context, texType, level))
3985*8975f5c5SAndroid Build Coastguard Worker {
3986*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3987*8975f5c5SAndroid Build Coastguard Worker return false;
3988*8975f5c5SAndroid Build Coastguard Worker }
3989*8975f5c5SAndroid Build Coastguard Worker
3990*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
3991*8975f5c5SAndroid Build Coastguard Worker Framebuffer *readFramebuffer = state.getReadFramebuffer();
3992*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
3993*8975f5c5SAndroid Build Coastguard Worker {
3994*8975f5c5SAndroid Build Coastguard Worker return false;
3995*8975f5c5SAndroid Build Coastguard Worker }
3996*8975f5c5SAndroid Build Coastguard Worker
3997*8975f5c5SAndroid Build Coastguard Worker // checkReadBufferResourceSamples = true. Treat renderToTexture textures as single sample since
3998*8975f5c5SAndroid Build Coastguard Worker // they will be resolved before copying.
3999*8975f5c5SAndroid Build Coastguard Worker if (!readFramebuffer->isDefault() &&
4000*8975f5c5SAndroid Build Coastguard Worker !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true))
4001*8975f5c5SAndroid Build Coastguard Worker {
4002*8975f5c5SAndroid Build Coastguard Worker return false;
4003*8975f5c5SAndroid Build Coastguard Worker }
4004*8975f5c5SAndroid Build Coastguard Worker
4005*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->getReadBufferState() == GL_NONE)
4006*8975f5c5SAndroid Build Coastguard Worker {
4007*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNone);
4008*8975f5c5SAndroid Build Coastguard Worker return false;
4009*8975f5c5SAndroid Build Coastguard Worker }
4010*8975f5c5SAndroid Build Coastguard Worker
4011*8975f5c5SAndroid Build Coastguard Worker // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
4012*8975f5c5SAndroid Build Coastguard Worker // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
4013*8975f5c5SAndroid Build Coastguard Worker // attachment and WebGL defines it to be an error. We do the check unconditionally as the
4014*8975f5c5SAndroid Build Coastguard Worker // situation is an application error that would lead to a crash in ANGLE.
4015*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *source = readFramebuffer->getReadColorAttachment();
4016*8975f5c5SAndroid Build Coastguard Worker if (source == nullptr)
4017*8975f5c5SAndroid Build Coastguard Worker {
4018*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingReadAttachment);
4019*8975f5c5SAndroid Build Coastguard Worker return false;
4020*8975f5c5SAndroid Build Coastguard Worker }
4021*8975f5c5SAndroid Build Coastguard Worker
4022*8975f5c5SAndroid Build Coastguard Worker if (source->isYUV())
4023*8975f5c5SAndroid Build Coastguard Worker {
4024*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCopyFromYUVFramebuffer);
4025*8975f5c5SAndroid Build Coastguard Worker return false;
4026*8975f5c5SAndroid Build Coastguard Worker }
4027*8975f5c5SAndroid Build Coastguard Worker
4028*8975f5c5SAndroid Build Coastguard Worker // OVR_multiview spec:
4029*8975f5c5SAndroid Build Coastguard Worker // INVALID_FRAMEBUFFER_OPERATION is generated by commands that read from the
4030*8975f5c5SAndroid Build Coastguard Worker // framebuffer such as BlitFramebuffer, ReadPixels, CopyTexImage*, and
4031*8975f5c5SAndroid Build Coastguard Worker // CopyTexSubImage*, if the number of views in the current read framebuffer
4032*8975f5c5SAndroid Build Coastguard Worker // is greater than 1.
4033*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->readDisallowedByMultiview())
4034*8975f5c5SAndroid Build Coastguard Worker {
4035*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
4036*8975f5c5SAndroid Build Coastguard Worker return false;
4037*8975f5c5SAndroid Build Coastguard Worker }
4038*8975f5c5SAndroid Build Coastguard Worker
4039*8975f5c5SAndroid Build Coastguard Worker const Caps &caps = context->getCaps();
4040*8975f5c5SAndroid Build Coastguard Worker
4041*8975f5c5SAndroid Build Coastguard Worker GLint maxDimension = 0;
4042*8975f5c5SAndroid Build Coastguard Worker switch (texType)
4043*8975f5c5SAndroid Build Coastguard Worker {
4044*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2D:
4045*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.max2DTextureSize;
4046*8975f5c5SAndroid Build Coastguard Worker break;
4047*8975f5c5SAndroid Build Coastguard Worker
4048*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMap:
4049*8975f5c5SAndroid Build Coastguard Worker case TextureType::CubeMapArray:
4050*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.maxCubeMapTextureSize;
4051*8975f5c5SAndroid Build Coastguard Worker break;
4052*8975f5c5SAndroid Build Coastguard Worker
4053*8975f5c5SAndroid Build Coastguard Worker case TextureType::Rectangle:
4054*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.maxRectangleTextureSize;
4055*8975f5c5SAndroid Build Coastguard Worker break;
4056*8975f5c5SAndroid Build Coastguard Worker
4057*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DArray:
4058*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.max2DTextureSize;
4059*8975f5c5SAndroid Build Coastguard Worker break;
4060*8975f5c5SAndroid Build Coastguard Worker
4061*8975f5c5SAndroid Build Coastguard Worker case TextureType::_3D:
4062*8975f5c5SAndroid Build Coastguard Worker maxDimension = caps.max3DTextureSize;
4063*8975f5c5SAndroid Build Coastguard Worker break;
4064*8975f5c5SAndroid Build Coastguard Worker
4065*8975f5c5SAndroid Build Coastguard Worker default:
4066*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
4067*8975f5c5SAndroid Build Coastguard Worker return false;
4068*8975f5c5SAndroid Build Coastguard Worker }
4069*8975f5c5SAndroid Build Coastguard Worker
4070*8975f5c5SAndroid Build Coastguard Worker Texture *texture = state.getTargetTexture(texType);
4071*8975f5c5SAndroid Build Coastguard Worker if (!texture)
4072*8975f5c5SAndroid Build Coastguard Worker {
4073*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureNotBound);
4074*8975f5c5SAndroid Build Coastguard Worker return false;
4075*8975f5c5SAndroid Build Coastguard Worker }
4076*8975f5c5SAndroid Build Coastguard Worker
4077*8975f5c5SAndroid Build Coastguard Worker if (texture->getImmutableFormat() && !isSubImage)
4078*8975f5c5SAndroid Build Coastguard Worker {
4079*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsImmutable);
4080*8975f5c5SAndroid Build Coastguard Worker return false;
4081*8975f5c5SAndroid Build Coastguard Worker }
4082*8975f5c5SAndroid Build Coastguard Worker
4083*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo =
4084*8975f5c5SAndroid Build Coastguard Worker isSubImage ? *texture->getFormat(target, level).info
4085*8975f5c5SAndroid Build Coastguard Worker : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
4086*8975f5c5SAndroid Build Coastguard Worker
4087*8975f5c5SAndroid Build Coastguard Worker if (formatInfo.depthBits > 0 || formatInfo.compressed)
4088*8975f5c5SAndroid Build Coastguard Worker {
4089*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
4090*8975f5c5SAndroid Build Coastguard Worker return false;
4091*8975f5c5SAndroid Build Coastguard Worker }
4092*8975f5c5SAndroid Build Coastguard Worker
4093*8975f5c5SAndroid Build Coastguard Worker if (isSubImage)
4094*8975f5c5SAndroid Build Coastguard Worker {
4095*8975f5c5SAndroid Build Coastguard Worker if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
4096*8975f5c5SAndroid Build Coastguard Worker static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
4097*8975f5c5SAndroid Build Coastguard Worker static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
4098*8975f5c5SAndroid Build Coastguard Worker {
4099*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
4100*8975f5c5SAndroid Build Coastguard Worker return false;
4101*8975f5c5SAndroid Build Coastguard Worker }
4102*8975f5c5SAndroid Build Coastguard Worker }
4103*8975f5c5SAndroid Build Coastguard Worker else
4104*8975f5c5SAndroid Build Coastguard Worker {
4105*8975f5c5SAndroid Build Coastguard Worker if ((texType == TextureType::CubeMap || texType == TextureType::CubeMapArray) &&
4106*8975f5c5SAndroid Build Coastguard Worker width != height)
4107*8975f5c5SAndroid Build Coastguard Worker {
4108*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapIncomplete);
4109*8975f5c5SAndroid Build Coastguard Worker return false;
4110*8975f5c5SAndroid Build Coastguard Worker }
4111*8975f5c5SAndroid Build Coastguard Worker
4112*8975f5c5SAndroid Build Coastguard Worker if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
4113*8975f5c5SAndroid Build Coastguard Worker {
4114*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, internalformat);
4115*8975f5c5SAndroid Build Coastguard Worker return false;
4116*8975f5c5SAndroid Build Coastguard Worker }
4117*8975f5c5SAndroid Build Coastguard Worker
4118*8975f5c5SAndroid Build Coastguard Worker int maxLevelDimension = (maxDimension >> level);
4119*8975f5c5SAndroid Build Coastguard Worker if (static_cast<int>(width) > maxLevelDimension ||
4120*8975f5c5SAndroid Build Coastguard Worker static_cast<int>(height) > maxLevelDimension)
4121*8975f5c5SAndroid Build Coastguard Worker {
4122*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
4123*8975f5c5SAndroid Build Coastguard Worker return false;
4124*8975f5c5SAndroid Build Coastguard Worker }
4125*8975f5c5SAndroid Build Coastguard Worker }
4126*8975f5c5SAndroid Build Coastguard Worker
4127*8975f5c5SAndroid Build Coastguard Worker // Do not leak the previous texture format for non-subImage case.
4128*8975f5c5SAndroid Build Coastguard Worker if (textureFormatOut && isSubImage)
4129*8975f5c5SAndroid Build Coastguard Worker {
4130*8975f5c5SAndroid Build Coastguard Worker *textureFormatOut = texture->getFormat(target, level);
4131*8975f5c5SAndroid Build Coastguard Worker }
4132*8975f5c5SAndroid Build Coastguard Worker
4133*8975f5c5SAndroid Build Coastguard Worker // Detect texture copying feedback loops for WebGL.
4134*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL())
4135*8975f5c5SAndroid Build Coastguard Worker {
4136*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
4137*8975f5c5SAndroid Build Coastguard Worker {
4138*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFeedbackLoop);
4139*8975f5c5SAndroid Build Coastguard Worker return false;
4140*8975f5c5SAndroid Build Coastguard Worker }
4141*8975f5c5SAndroid Build Coastguard Worker }
4142*8975f5c5SAndroid Build Coastguard Worker
4143*8975f5c5SAndroid Build Coastguard Worker return true;
4144*8975f5c5SAndroid Build Coastguard Worker }
4145*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramPipelineDrawStates(const Context * context,const Extensions & extensions,ProgramPipeline * programPipeline)4146*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramPipelineDrawStates(const Context *context,
4147*8975f5c5SAndroid Build Coastguard Worker const Extensions &extensions,
4148*8975f5c5SAndroid Build Coastguard Worker ProgramPipeline *programPipeline)
4149*8975f5c5SAndroid Build Coastguard Worker {
4150*8975f5c5SAndroid Build Coastguard Worker for (const ShaderType shaderType : gl::AllShaderTypes())
4151*8975f5c5SAndroid Build Coastguard Worker {
4152*8975f5c5SAndroid Build Coastguard Worker const SharedProgramExecutable &executable =
4153*8975f5c5SAndroid Build Coastguard Worker programPipeline->getShaderProgramExecutable(shaderType);
4154*8975f5c5SAndroid Build Coastguard Worker if (executable)
4155*8975f5c5SAndroid Build Coastguard Worker {
4156*8975f5c5SAndroid Build Coastguard Worker const char *errorMsg = ValidateProgramDrawStates(context, extensions, *executable);
4157*8975f5c5SAndroid Build Coastguard Worker if (errorMsg)
4158*8975f5c5SAndroid Build Coastguard Worker {
4159*8975f5c5SAndroid Build Coastguard Worker return errorMsg;
4160*8975f5c5SAndroid Build Coastguard Worker }
4161*8975f5c5SAndroid Build Coastguard Worker }
4162*8975f5c5SAndroid Build Coastguard Worker }
4163*8975f5c5SAndroid Build Coastguard Worker
4164*8975f5c5SAndroid Build Coastguard Worker return nullptr;
4165*8975f5c5SAndroid Build Coastguard Worker }
4166*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramPipelineAttachedPrograms(ProgramPipeline * programPipeline)4167*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline)
4168*8975f5c5SAndroid Build Coastguard Worker {
4169*8975f5c5SAndroid Build Coastguard Worker // An INVALID_OPERATION error is generated by any command that transfers vertices to the
4170*8975f5c5SAndroid Build Coastguard Worker // GL or launches compute work if the current set of active
4171*8975f5c5SAndroid Build Coastguard Worker // program objects cannot be executed, for reasons including:
4172*8975f5c5SAndroid Build Coastguard Worker // - There is no current program object specified by UseProgram, there is a current program
4173*8975f5c5SAndroid Build Coastguard Worker // pipeline object, and that object is empty (no executable code is installed for any stage).
4174*8975f5c5SAndroid Build Coastguard Worker // - A program object is active for at least one, but not all of the shader
4175*8975f5c5SAndroid Build Coastguard Worker // stages that were present when the program was linked.
4176*8975f5c5SAndroid Build Coastguard Worker if (!programPipeline->getExecutable().getLinkedShaderStages().any())
4177*8975f5c5SAndroid Build Coastguard Worker {
4178*8975f5c5SAndroid Build Coastguard Worker return gl::err::kNoExecutableCodeInstalled;
4179*8975f5c5SAndroid Build Coastguard Worker }
4180*8975f5c5SAndroid Build Coastguard Worker for (const ShaderType shaderType : gl::AllShaderTypes())
4181*8975f5c5SAndroid Build Coastguard Worker {
4182*8975f5c5SAndroid Build Coastguard Worker const Program *shaderProgram = programPipeline->getShaderProgram(shaderType);
4183*8975f5c5SAndroid Build Coastguard Worker if (shaderProgram)
4184*8975f5c5SAndroid Build Coastguard Worker {
4185*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &executable = shaderProgram->getExecutable();
4186*8975f5c5SAndroid Build Coastguard Worker for (const ShaderType programShaderType : executable.getLinkedShaderStages())
4187*8975f5c5SAndroid Build Coastguard Worker {
4188*8975f5c5SAndroid Build Coastguard Worker if (shaderProgram != programPipeline->getShaderProgram(programShaderType))
4189*8975f5c5SAndroid Build Coastguard Worker {
4190*8975f5c5SAndroid Build Coastguard Worker return gl::err::kNotAllStagesOfSeparableProgramUsed;
4191*8975f5c5SAndroid Build Coastguard Worker }
4192*8975f5c5SAndroid Build Coastguard Worker }
4193*8975f5c5SAndroid Build Coastguard Worker }
4194*8975f5c5SAndroid Build Coastguard Worker }
4195*8975f5c5SAndroid Build Coastguard Worker
4196*8975f5c5SAndroid Build Coastguard Worker // [EXT_geometry_shader] Section 11.1.gs Geometry Shaders
4197*8975f5c5SAndroid Build Coastguard Worker // A non-separable program object or program pipeline object that includes
4198*8975f5c5SAndroid Build Coastguard Worker // a geometry shader must also include a vertex shader.
4199*8975f5c5SAndroid Build Coastguard Worker // An INVALID_OPERATION error is generated by any command that transfers
4200*8975f5c5SAndroid Build Coastguard Worker // vertices to the GL if the current program state has a geometry shader
4201*8975f5c5SAndroid Build Coastguard Worker // but no vertex shader.
4202*8975f5c5SAndroid Build Coastguard Worker if (!programPipeline->getShaderProgram(ShaderType::Vertex) &&
4203*8975f5c5SAndroid Build Coastguard Worker programPipeline->getShaderProgram(ShaderType::Geometry))
4204*8975f5c5SAndroid Build Coastguard Worker {
4205*8975f5c5SAndroid Build Coastguard Worker return gl::err::kNoActiveGraphicsShaderStage;
4206*8975f5c5SAndroid Build Coastguard Worker }
4207*8975f5c5SAndroid Build Coastguard Worker
4208*8975f5c5SAndroid Build Coastguard Worker return nullptr;
4209*8975f5c5SAndroid Build Coastguard Worker }
4210*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawStates(const Context * context,GLenum * outErrorCode)4211*8975f5c5SAndroid Build Coastguard Worker const char *ValidateDrawStates(const Context *context, GLenum *outErrorCode)
4212*8975f5c5SAndroid Build Coastguard Worker {
4213*8975f5c5SAndroid Build Coastguard Worker // Note all errors returned from this function are INVALID_OPERATION except for the draw
4214*8975f5c5SAndroid Build Coastguard Worker // framebuffer completeness check.
4215*8975f5c5SAndroid Build Coastguard Worker *outErrorCode = GL_INVALID_OPERATION;
4216*8975f5c5SAndroid Build Coastguard Worker
4217*8975f5c5SAndroid Build Coastguard Worker const Extensions &extensions = context->getExtensions();
4218*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
4219*8975f5c5SAndroid Build Coastguard Worker
4220*8975f5c5SAndroid Build Coastguard Worker // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
4221*8975f5c5SAndroid Build Coastguard Worker // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
4222*8975f5c5SAndroid Build Coastguard Worker // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
4223*8975f5c5SAndroid Build Coastguard Worker VertexArray *vertexArray = state.getVertexArray();
4224*8975f5c5SAndroid Build Coastguard Worker ASSERT(vertexArray);
4225*8975f5c5SAndroid Build Coastguard Worker
4226*8975f5c5SAndroid Build Coastguard Worker if (!extensions.webglCompatibilityANGLE && vertexArray->hasInvalidMappedArrayBuffer())
4227*8975f5c5SAndroid Build Coastguard Worker {
4228*8975f5c5SAndroid Build Coastguard Worker return kBufferMapped;
4229*8975f5c5SAndroid Build Coastguard Worker }
4230*8975f5c5SAndroid Build Coastguard Worker
4231*8975f5c5SAndroid Build Coastguard Worker // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
4232*8975f5c5SAndroid Build Coastguard Worker // Section 6.10 of the WebGL 1.0 spec.
4233*8975f5c5SAndroid Build Coastguard Worker Framebuffer *framebuffer = state.getDrawFramebuffer();
4234*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
4235*8975f5c5SAndroid Build Coastguard Worker
4236*8975f5c5SAndroid Build Coastguard Worker if (context->getLimitations().noSeparateStencilRefsAndMasks ||
4237*8975f5c5SAndroid Build Coastguard Worker extensions.webglCompatibilityANGLE)
4238*8975f5c5SAndroid Build Coastguard Worker {
4239*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
4240*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *dsAttachment =
4241*8975f5c5SAndroid Build Coastguard Worker framebuffer->getStencilOrDepthStencilAttachment();
4242*8975f5c5SAndroid Build Coastguard Worker const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
4243*8975f5c5SAndroid Build Coastguard Worker ASSERT(stencilBits <= 8);
4244*8975f5c5SAndroid Build Coastguard Worker
4245*8975f5c5SAndroid Build Coastguard Worker const DepthStencilState &depthStencilState = state.getDepthStencilState();
4246*8975f5c5SAndroid Build Coastguard Worker if (depthStencilState.stencilTest && stencilBits > 0)
4247*8975f5c5SAndroid Build Coastguard Worker {
4248*8975f5c5SAndroid Build Coastguard Worker auto maxStencilValue = angle::BitMask<GLuint>(stencilBits);
4249*8975f5c5SAndroid Build Coastguard Worker
4250*8975f5c5SAndroid Build Coastguard Worker bool differentRefs =
4251*8975f5c5SAndroid Build Coastguard Worker clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
4252*8975f5c5SAndroid Build Coastguard Worker clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
4253*8975f5c5SAndroid Build Coastguard Worker bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
4254*8975f5c5SAndroid Build Coastguard Worker (depthStencilState.stencilBackWritemask & maxStencilValue);
4255*8975f5c5SAndroid Build Coastguard Worker bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
4256*8975f5c5SAndroid Build Coastguard Worker (depthStencilState.stencilBackMask & maxStencilValue);
4257*8975f5c5SAndroid Build Coastguard Worker
4258*8975f5c5SAndroid Build Coastguard Worker if (differentRefs || differentWritemasks || differentMasks)
4259*8975f5c5SAndroid Build Coastguard Worker {
4260*8975f5c5SAndroid Build Coastguard Worker if (!extensions.webglCompatibilityANGLE)
4261*8975f5c5SAndroid Build Coastguard Worker {
4262*8975f5c5SAndroid Build Coastguard Worker WARN() << "This ANGLE implementation does not support separate front/back "
4263*8975f5c5SAndroid Build Coastguard Worker "stencil writemasks, reference values, or stencil mask values.";
4264*8975f5c5SAndroid Build Coastguard Worker }
4265*8975f5c5SAndroid Build Coastguard Worker return kStencilReferenceMaskOrMismatch;
4266*8975f5c5SAndroid Build Coastguard Worker }
4267*8975f5c5SAndroid Build Coastguard Worker }
4268*8975f5c5SAndroid Build Coastguard Worker }
4269*8975f5c5SAndroid Build Coastguard Worker
4270*8975f5c5SAndroid Build Coastguard Worker if (!extensions.floatBlendEXT)
4271*8975f5c5SAndroid Build Coastguard Worker {
4272*8975f5c5SAndroid Build Coastguard Worker const DrawBufferMask blendEnabledActiveFloat32ColorAttachmentDrawBufferMask =
4273*8975f5c5SAndroid Build Coastguard Worker state.getBlendEnabledDrawBufferMask() &
4274*8975f5c5SAndroid Build Coastguard Worker framebuffer->getActiveFloat32ColorAttachmentDrawBufferMask();
4275*8975f5c5SAndroid Build Coastguard Worker if (blendEnabledActiveFloat32ColorAttachmentDrawBufferMask.any())
4276*8975f5c5SAndroid Build Coastguard Worker {
4277*8975f5c5SAndroid Build Coastguard Worker return kUnsupportedFloatBlending;
4278*8975f5c5SAndroid Build Coastguard Worker }
4279*8975f5c5SAndroid Build Coastguard Worker }
4280*8975f5c5SAndroid Build Coastguard Worker
4281*8975f5c5SAndroid Build Coastguard Worker if (extensions.renderSharedExponentQCOM)
4282*8975f5c5SAndroid Build Coastguard Worker {
4283*8975f5c5SAndroid Build Coastguard Worker if (!ValidateColorMasksForSharedExponentColorBuffers(state.getBlendStateExt(), framebuffer))
4284*8975f5c5SAndroid Build Coastguard Worker {
4285*8975f5c5SAndroid Build Coastguard Worker return kUnsupportedColorMaskForSharedExponentColorBuffer;
4286*8975f5c5SAndroid Build Coastguard Worker }
4287*8975f5c5SAndroid Build Coastguard Worker }
4288*8975f5c5SAndroid Build Coastguard Worker
4289*8975f5c5SAndroid Build Coastguard Worker if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4290*8975f5c5SAndroid Build Coastguard Worker extensions.webglCompatibilityANGLE)
4291*8975f5c5SAndroid Build Coastguard Worker {
4292*8975f5c5SAndroid Build Coastguard Worker if (state.hasSimultaneousConstantColorAndAlphaBlendFunc())
4293*8975f5c5SAndroid Build Coastguard Worker {
4294*8975f5c5SAndroid Build Coastguard Worker if (extensions.webglCompatibilityANGLE)
4295*8975f5c5SAndroid Build Coastguard Worker {
4296*8975f5c5SAndroid Build Coastguard Worker return kInvalidConstantColor;
4297*8975f5c5SAndroid Build Coastguard Worker }
4298*8975f5c5SAndroid Build Coastguard Worker
4299*8975f5c5SAndroid Build Coastguard Worker WARN() << kConstantColorAlphaLimitation;
4300*8975f5c5SAndroid Build Coastguard Worker return kConstantColorAlphaLimitation;
4301*8975f5c5SAndroid Build Coastguard Worker }
4302*8975f5c5SAndroid Build Coastguard Worker }
4303*8975f5c5SAndroid Build Coastguard Worker
4304*8975f5c5SAndroid Build Coastguard Worker const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
4305*8975f5c5SAndroid Build Coastguard Worker if (!framebufferStatus.isComplete())
4306*8975f5c5SAndroid Build Coastguard Worker {
4307*8975f5c5SAndroid Build Coastguard Worker *outErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION;
4308*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebufferStatus.reason);
4309*8975f5c5SAndroid Build Coastguard Worker return framebufferStatus.reason;
4310*8975f5c5SAndroid Build Coastguard Worker }
4311*8975f5c5SAndroid Build Coastguard Worker
4312*8975f5c5SAndroid Build Coastguard Worker bool framebufferIsYUV = framebuffer->hasYUVAttachment();
4313*8975f5c5SAndroid Build Coastguard Worker if (framebufferIsYUV)
4314*8975f5c5SAndroid Build Coastguard Worker {
4315*8975f5c5SAndroid Build Coastguard Worker const BlendState &blendState = state.getBlendState();
4316*8975f5c5SAndroid Build Coastguard Worker if (!blendState.colorMaskRed || !blendState.colorMaskGreen || !blendState.colorMaskBlue)
4317*8975f5c5SAndroid Build Coastguard Worker {
4318*8975f5c5SAndroid Build Coastguard Worker // When rendering into a YUV framebuffer, the color mask must have r g and b set to
4319*8975f5c5SAndroid Build Coastguard Worker // true.
4320*8975f5c5SAndroid Build Coastguard Worker return kInvalidColorMaskForYUV;
4321*8975f5c5SAndroid Build Coastguard Worker }
4322*8975f5c5SAndroid Build Coastguard Worker
4323*8975f5c5SAndroid Build Coastguard Worker if (blendState.blend)
4324*8975f5c5SAndroid Build Coastguard Worker {
4325*8975f5c5SAndroid Build Coastguard Worker // When rendering into a YUV framebuffer, blending must be disabled.
4326*8975f5c5SAndroid Build Coastguard Worker return kInvalidBlendStateForYUV;
4327*8975f5c5SAndroid Build Coastguard Worker }
4328*8975f5c5SAndroid Build Coastguard Worker }
4329*8975f5c5SAndroid Build Coastguard Worker else
4330*8975f5c5SAndroid Build Coastguard Worker {
4331*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->hasExternalTextureAttachment())
4332*8975f5c5SAndroid Build Coastguard Worker {
4333*8975f5c5SAndroid Build Coastguard Worker // It is an error to render into an external texture that is not YUV.
4334*8975f5c5SAndroid Build Coastguard Worker return kExternalTextureAttachmentNotYUV;
4335*8975f5c5SAndroid Build Coastguard Worker }
4336*8975f5c5SAndroid Build Coastguard Worker }
4337*8975f5c5SAndroid Build Coastguard Worker
4338*8975f5c5SAndroid Build Coastguard Worker // Advanced blend equation can only be enabled for a single render target.
4339*8975f5c5SAndroid Build Coastguard Worker const BlendStateExt &blendStateExt = state.getBlendStateExt();
4340*8975f5c5SAndroid Build Coastguard Worker if (blendStateExt.getUsesAdvancedBlendEquationMask().any())
4341*8975f5c5SAndroid Build Coastguard Worker {
4342*8975f5c5SAndroid Build Coastguard Worker const size_t drawBufferCount = framebuffer->getDrawbufferStateCount();
4343*8975f5c5SAndroid Build Coastguard Worker uint32_t advancedBlendRenderTargetCount = 0;
4344*8975f5c5SAndroid Build Coastguard Worker
4345*8975f5c5SAndroid Build Coastguard Worker for (size_t drawBufferIndex : blendStateExt.getUsesAdvancedBlendEquationMask())
4346*8975f5c5SAndroid Build Coastguard Worker {
4347*8975f5c5SAndroid Build Coastguard Worker if (drawBufferIndex < drawBufferCount &&
4348*8975f5c5SAndroid Build Coastguard Worker framebuffer->getDrawBufferState(drawBufferIndex) != GL_NONE &&
4349*8975f5c5SAndroid Build Coastguard Worker blendStateExt.getEnabledMask().test(drawBufferIndex) &&
4350*8975f5c5SAndroid Build Coastguard Worker blendStateExt.getUsesAdvancedBlendEquationMask().test(drawBufferIndex))
4351*8975f5c5SAndroid Build Coastguard Worker {
4352*8975f5c5SAndroid Build Coastguard Worker ++advancedBlendRenderTargetCount;
4353*8975f5c5SAndroid Build Coastguard Worker }
4354*8975f5c5SAndroid Build Coastguard Worker }
4355*8975f5c5SAndroid Build Coastguard Worker
4356*8975f5c5SAndroid Build Coastguard Worker if (advancedBlendRenderTargetCount > 1)
4357*8975f5c5SAndroid Build Coastguard Worker {
4358*8975f5c5SAndroid Build Coastguard Worker return kAdvancedBlendEquationWithMRT;
4359*8975f5c5SAndroid Build Coastguard Worker }
4360*8975f5c5SAndroid Build Coastguard Worker }
4361*8975f5c5SAndroid Build Coastguard Worker
4362*8975f5c5SAndroid Build Coastguard Worker // Dual-source blending functions limit the number of supported draw buffers.
4363*8975f5c5SAndroid Build Coastguard Worker if (blendStateExt.getUsesExtendedBlendFactorMask().any())
4364*8975f5c5SAndroid Build Coastguard Worker {
4365*8975f5c5SAndroid Build Coastguard Worker // Imply the strictest spec interpretation to pass on all OpenGL drivers:
4366*8975f5c5SAndroid Build Coastguard Worker // dual-source blending is considered active if the blend state contains
4367*8975f5c5SAndroid Build Coastguard Worker // any SRC1 factor no matter what.
4368*8975f5c5SAndroid Build Coastguard Worker const size_t drawBufferCount = framebuffer->getDrawbufferStateCount();
4369*8975f5c5SAndroid Build Coastguard Worker for (size_t drawBufferIndex = context->getCaps().maxDualSourceDrawBuffers;
4370*8975f5c5SAndroid Build Coastguard Worker drawBufferIndex < drawBufferCount; ++drawBufferIndex)
4371*8975f5c5SAndroid Build Coastguard Worker {
4372*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->getDrawBufferState(drawBufferIndex) != GL_NONE)
4373*8975f5c5SAndroid Build Coastguard Worker {
4374*8975f5c5SAndroid Build Coastguard Worker return kDualSourceBlendingDrawBuffersLimit;
4375*8975f5c5SAndroid Build Coastguard Worker }
4376*8975f5c5SAndroid Build Coastguard Worker }
4377*8975f5c5SAndroid Build Coastguard Worker }
4378*8975f5c5SAndroid Build Coastguard Worker
4379*8975f5c5SAndroid Build Coastguard Worker if (context->getStateCache().hasAnyEnabledClientAttrib())
4380*8975f5c5SAndroid Build Coastguard Worker {
4381*8975f5c5SAndroid Build Coastguard Worker if (extensions.webglCompatibilityANGLE || !state.areClientArraysEnabled())
4382*8975f5c5SAndroid Build Coastguard Worker {
4383*8975f5c5SAndroid Build Coastguard Worker // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
4384*8975f5c5SAndroid Build Coastguard Worker // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
4385*8975f5c5SAndroid Build Coastguard Worker // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
4386*8975f5c5SAndroid Build Coastguard Worker // to drawArrays or drawElements will generate an INVALID_OPERATION error.
4387*8975f5c5SAndroid Build Coastguard Worker return kVertexArrayNoBuffer;
4388*8975f5c5SAndroid Build Coastguard Worker }
4389*8975f5c5SAndroid Build Coastguard Worker
4390*8975f5c5SAndroid Build Coastguard Worker if (state.getVertexArray()->hasEnabledNullPointerClientArray())
4391*8975f5c5SAndroid Build Coastguard Worker {
4392*8975f5c5SAndroid Build Coastguard Worker // This is an application error that would normally result in a crash, but we catch it
4393*8975f5c5SAndroid Build Coastguard Worker // and return an error
4394*8975f5c5SAndroid Build Coastguard Worker return kVertexArrayNoBufferPointer;
4395*8975f5c5SAndroid Build Coastguard Worker }
4396*8975f5c5SAndroid Build Coastguard Worker }
4397*8975f5c5SAndroid Build Coastguard Worker
4398*8975f5c5SAndroid Build Coastguard Worker // If we are running GLES1, there is no current program.
4399*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() >= Version(2, 0))
4400*8975f5c5SAndroid Build Coastguard Worker {
4401*8975f5c5SAndroid Build Coastguard Worker Program *program = state.getLinkedProgram(context);
4402*8975f5c5SAndroid Build Coastguard Worker ProgramPipeline *programPipeline = state.getLinkedProgramPipeline(context);
4403*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = state.getProgramExecutable();
4404*8975f5c5SAndroid Build Coastguard Worker
4405*8975f5c5SAndroid Build Coastguard Worker bool programIsYUVOutput = false;
4406*8975f5c5SAndroid Build Coastguard Worker
4407*8975f5c5SAndroid Build Coastguard Worker if (program)
4408*8975f5c5SAndroid Build Coastguard Worker {
4409*8975f5c5SAndroid Build Coastguard Worker const char *errorMsg = ValidateProgramDrawStates(context, extensions, *executable);
4410*8975f5c5SAndroid Build Coastguard Worker if (errorMsg)
4411*8975f5c5SAndroid Build Coastguard Worker {
4412*8975f5c5SAndroid Build Coastguard Worker return errorMsg;
4413*8975f5c5SAndroid Build Coastguard Worker }
4414*8975f5c5SAndroid Build Coastguard Worker
4415*8975f5c5SAndroid Build Coastguard Worker programIsYUVOutput = executable->isYUVOutput();
4416*8975f5c5SAndroid Build Coastguard Worker }
4417*8975f5c5SAndroid Build Coastguard Worker else if (programPipeline)
4418*8975f5c5SAndroid Build Coastguard Worker {
4419*8975f5c5SAndroid Build Coastguard Worker const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline);
4420*8975f5c5SAndroid Build Coastguard Worker if (errorMsg)
4421*8975f5c5SAndroid Build Coastguard Worker {
4422*8975f5c5SAndroid Build Coastguard Worker return errorMsg;
4423*8975f5c5SAndroid Build Coastguard Worker }
4424*8975f5c5SAndroid Build Coastguard Worker
4425*8975f5c5SAndroid Build Coastguard Worker errorMsg = ValidateProgramPipelineDrawStates(context, extensions, programPipeline);
4426*8975f5c5SAndroid Build Coastguard Worker if (errorMsg)
4427*8975f5c5SAndroid Build Coastguard Worker {
4428*8975f5c5SAndroid Build Coastguard Worker return errorMsg;
4429*8975f5c5SAndroid Build Coastguard Worker }
4430*8975f5c5SAndroid Build Coastguard Worker
4431*8975f5c5SAndroid Build Coastguard Worker if (!programPipeline->isLinked())
4432*8975f5c5SAndroid Build Coastguard Worker {
4433*8975f5c5SAndroid Build Coastguard Worker return kProgramPipelineLinkFailed;
4434*8975f5c5SAndroid Build Coastguard Worker }
4435*8975f5c5SAndroid Build Coastguard Worker
4436*8975f5c5SAndroid Build Coastguard Worker programIsYUVOutput = executable->isYUVOutput();
4437*8975f5c5SAndroid Build Coastguard Worker }
4438*8975f5c5SAndroid Build Coastguard Worker
4439*8975f5c5SAndroid Build Coastguard Worker if (executable)
4440*8975f5c5SAndroid Build Coastguard Worker {
4441*8975f5c5SAndroid Build Coastguard Worker if (!executable->validateSamplers(context->getCaps()))
4442*8975f5c5SAndroid Build Coastguard Worker {
4443*8975f5c5SAndroid Build Coastguard Worker return kTextureTypeConflict;
4444*8975f5c5SAndroid Build Coastguard Worker }
4445*8975f5c5SAndroid Build Coastguard Worker
4446*8975f5c5SAndroid Build Coastguard Worker if (executable->hasLinkedTessellationShader())
4447*8975f5c5SAndroid Build Coastguard Worker {
4448*8975f5c5SAndroid Build Coastguard Worker if (!executable->hasLinkedShaderStage(ShaderType::Vertex))
4449*8975f5c5SAndroid Build Coastguard Worker {
4450*8975f5c5SAndroid Build Coastguard Worker return kTessellationShaderRequiresVertexShader;
4451*8975f5c5SAndroid Build Coastguard Worker }
4452*8975f5c5SAndroid Build Coastguard Worker
4453*8975f5c5SAndroid Build Coastguard Worker if (!executable->hasLinkedShaderStage(ShaderType::TessControl) ||
4454*8975f5c5SAndroid Build Coastguard Worker !executable->hasLinkedShaderStage(ShaderType::TessEvaluation))
4455*8975f5c5SAndroid Build Coastguard Worker {
4456*8975f5c5SAndroid Build Coastguard Worker return kTessellationShaderRequiresBothControlAndEvaluation;
4457*8975f5c5SAndroid Build Coastguard Worker }
4458*8975f5c5SAndroid Build Coastguard Worker }
4459*8975f5c5SAndroid Build Coastguard Worker
4460*8975f5c5SAndroid Build Coastguard Worker if (state.isTransformFeedbackActive())
4461*8975f5c5SAndroid Build Coastguard Worker {
4462*8975f5c5SAndroid Build Coastguard Worker if (!ValidateProgramExecutableXFBBuffersPresent(context, executable))
4463*8975f5c5SAndroid Build Coastguard Worker {
4464*8975f5c5SAndroid Build Coastguard Worker return kTransformFeedbackBufferMissing;
4465*8975f5c5SAndroid Build Coastguard Worker }
4466*8975f5c5SAndroid Build Coastguard Worker }
4467*8975f5c5SAndroid Build Coastguard Worker }
4468*8975f5c5SAndroid Build Coastguard Worker
4469*8975f5c5SAndroid Build Coastguard Worker if (programIsYUVOutput != framebufferIsYUV)
4470*8975f5c5SAndroid Build Coastguard Worker {
4471*8975f5c5SAndroid Build Coastguard Worker // Both the program and framebuffer must match in YUV output state.
4472*8975f5c5SAndroid Build Coastguard Worker return kYUVOutputMissmatch;
4473*8975f5c5SAndroid Build Coastguard Worker }
4474*8975f5c5SAndroid Build Coastguard Worker
4475*8975f5c5SAndroid Build Coastguard Worker if (!state.validateSamplerFormats())
4476*8975f5c5SAndroid Build Coastguard Worker {
4477*8975f5c5SAndroid Build Coastguard Worker return kSamplerFormatMismatch;
4478*8975f5c5SAndroid Build Coastguard Worker }
4479*8975f5c5SAndroid Build Coastguard Worker
4480*8975f5c5SAndroid Build Coastguard Worker // Do some additional WebGL-specific validation
4481*8975f5c5SAndroid Build Coastguard Worker if (extensions.webglCompatibilityANGLE)
4482*8975f5c5SAndroid Build Coastguard Worker {
4483*8975f5c5SAndroid Build Coastguard Worker const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
4484*8975f5c5SAndroid Build Coastguard Worker if (state.isTransformFeedbackActive() &&
4485*8975f5c5SAndroid Build Coastguard Worker transformFeedbackObject->buffersBoundForOtherUseInWebGL())
4486*8975f5c5SAndroid Build Coastguard Worker {
4487*8975f5c5SAndroid Build Coastguard Worker return kTransformFeedbackBufferDoubleBound;
4488*8975f5c5SAndroid Build Coastguard Worker }
4489*8975f5c5SAndroid Build Coastguard Worker
4490*8975f5c5SAndroid Build Coastguard Worker // Detect rendering feedback loops for WebGL.
4491*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->formsRenderingFeedbackLoopWith(context))
4492*8975f5c5SAndroid Build Coastguard Worker {
4493*8975f5c5SAndroid Build Coastguard Worker return kFeedbackLoop;
4494*8975f5c5SAndroid Build Coastguard Worker }
4495*8975f5c5SAndroid Build Coastguard Worker
4496*8975f5c5SAndroid Build Coastguard Worker // Detect that the vertex shader input types match the attribute types
4497*8975f5c5SAndroid Build Coastguard Worker if (!ValidateVertexShaderAttributeTypeMatch(context))
4498*8975f5c5SAndroid Build Coastguard Worker {
4499*8975f5c5SAndroid Build Coastguard Worker return kVertexShaderTypeMismatch;
4500*8975f5c5SAndroid Build Coastguard Worker }
4501*8975f5c5SAndroid Build Coastguard Worker
4502*8975f5c5SAndroid Build Coastguard Worker if (!context->getState().getRasterizerState().rasterizerDiscard &&
4503*8975f5c5SAndroid Build Coastguard Worker !context->getState().allActiveDrawBufferChannelsMasked())
4504*8975f5c5SAndroid Build Coastguard Worker {
4505*8975f5c5SAndroid Build Coastguard Worker // Detect that if there's active color buffer without fragment shader output
4506*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFragmentShaderColorBufferMaskMatch(context))
4507*8975f5c5SAndroid Build Coastguard Worker {
4508*8975f5c5SAndroid Build Coastguard Worker return kDrawBufferMaskMismatch;
4509*8975f5c5SAndroid Build Coastguard Worker }
4510*8975f5c5SAndroid Build Coastguard Worker
4511*8975f5c5SAndroid Build Coastguard Worker // Detect that the color buffer types match the fragment shader output types
4512*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFragmentShaderColorBufferTypeMatch(context))
4513*8975f5c5SAndroid Build Coastguard Worker {
4514*8975f5c5SAndroid Build Coastguard Worker return kDrawBufferTypeMismatch;
4515*8975f5c5SAndroid Build Coastguard Worker }
4516*8975f5c5SAndroid Build Coastguard Worker }
4517*8975f5c5SAndroid Build Coastguard Worker
4518*8975f5c5SAndroid Build Coastguard Worker const VertexArray *vao = context->getState().getVertexArray();
4519*8975f5c5SAndroid Build Coastguard Worker if (vao->hasTransformFeedbackBindingConflict(context))
4520*8975f5c5SAndroid Build Coastguard Worker {
4521*8975f5c5SAndroid Build Coastguard Worker return kVertexBufferBoundForTransformFeedback;
4522*8975f5c5SAndroid Build Coastguard Worker }
4523*8975f5c5SAndroid Build Coastguard Worker
4524*8975f5c5SAndroid Build Coastguard Worker // Validate that we are rendering with a linked program.
4525*8975f5c5SAndroid Build Coastguard Worker if (!program->isLinked())
4526*8975f5c5SAndroid Build Coastguard Worker {
4527*8975f5c5SAndroid Build Coastguard Worker return kProgramNotLinked;
4528*8975f5c5SAndroid Build Coastguard Worker }
4529*8975f5c5SAndroid Build Coastguard Worker }
4530*8975f5c5SAndroid Build Coastguard Worker
4531*8975f5c5SAndroid Build Coastguard Worker // The QCOM_framebuffer_foveated spec:
4532*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->isFoveationEnabled())
4533*8975f5c5SAndroid Build Coastguard Worker {
4534*8975f5c5SAndroid Build Coastguard Worker ASSERT(extensions.framebufferFoveatedQCOM);
4535*8975f5c5SAndroid Build Coastguard Worker
4536*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if a rendering command is issued and the
4537*8975f5c5SAndroid Build Coastguard Worker // current bound program uses tessellation or geometry shaders.
4538*8975f5c5SAndroid Build Coastguard Worker if (executable->hasLinkedShaderStage(gl::ShaderType::Geometry) ||
4539*8975f5c5SAndroid Build Coastguard Worker executable->hasLinkedShaderStage(gl::ShaderType::TessControl) ||
4540*8975f5c5SAndroid Build Coastguard Worker executable->hasLinkedShaderStage(gl::ShaderType::TessEvaluation))
4541*8975f5c5SAndroid Build Coastguard Worker {
4542*8975f5c5SAndroid Build Coastguard Worker return err::kGeometryOrTessellationShaderBoundForFoveatedDraw;
4543*8975f5c5SAndroid Build Coastguard Worker }
4544*8975f5c5SAndroid Build Coastguard Worker
4545*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated by any API call which causes a framebuffer
4546*8975f5c5SAndroid Build Coastguard Worker // attachment to be written to if the framebuffer attachments have changed for
4547*8975f5c5SAndroid Build Coastguard Worker // a foveated fbo.
4548*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->hasAnyAttachmentChanged())
4549*8975f5c5SAndroid Build Coastguard Worker {
4550*8975f5c5SAndroid Build Coastguard Worker return err::kFramebufferFoveationAttachmentChanged;
4551*8975f5c5SAndroid Build Coastguard Worker }
4552*8975f5c5SAndroid Build Coastguard Worker }
4553*8975f5c5SAndroid Build Coastguard Worker }
4554*8975f5c5SAndroid Build Coastguard Worker
4555*8975f5c5SAndroid Build Coastguard Worker *outErrorCode = GL_NO_ERROR;
4556*8975f5c5SAndroid Build Coastguard Worker return nullptr;
4557*8975f5c5SAndroid Build Coastguard Worker }
4558*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramPipeline(const Context * context)4559*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramPipeline(const Context *context)
4560*8975f5c5SAndroid Build Coastguard Worker {
4561*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
4562*8975f5c5SAndroid Build Coastguard Worker // If we are running GLES1, there is no current program.
4563*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() >= Version(2, 0))
4564*8975f5c5SAndroid Build Coastguard Worker {
4565*8975f5c5SAndroid Build Coastguard Worker ProgramPipeline *programPipeline = state.getProgramPipeline();
4566*8975f5c5SAndroid Build Coastguard Worker if (programPipeline)
4567*8975f5c5SAndroid Build Coastguard Worker {
4568*8975f5c5SAndroid Build Coastguard Worker const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline);
4569*8975f5c5SAndroid Build Coastguard Worker if (errorMsg)
4570*8975f5c5SAndroid Build Coastguard Worker {
4571*8975f5c5SAndroid Build Coastguard Worker return errorMsg;
4572*8975f5c5SAndroid Build Coastguard Worker }
4573*8975f5c5SAndroid Build Coastguard Worker }
4574*8975f5c5SAndroid Build Coastguard Worker }
4575*8975f5c5SAndroid Build Coastguard Worker return nullptr;
4576*8975f5c5SAndroid Build Coastguard Worker }
4577*8975f5c5SAndroid Build Coastguard Worker
RecordDrawModeError(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode)4578*8975f5c5SAndroid Build Coastguard Worker void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode)
4579*8975f5c5SAndroid Build Coastguard Worker {
4580*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
4581*8975f5c5SAndroid Build Coastguard Worker TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
4582*8975f5c5SAndroid Build Coastguard Worker if (state.isTransformFeedbackActiveUnpaused())
4583*8975f5c5SAndroid Build Coastguard Worker {
4584*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTransformFeedbackPrimitiveMode(context, entryPoint,
4585*8975f5c5SAndroid Build Coastguard Worker curTransformFeedback->getPrimitiveMode(), mode))
4586*8975f5c5SAndroid Build Coastguard Worker {
4587*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
4588*8975f5c5SAndroid Build Coastguard Worker return;
4589*8975f5c5SAndroid Build Coastguard Worker }
4590*8975f5c5SAndroid Build Coastguard Worker }
4591*8975f5c5SAndroid Build Coastguard Worker
4592*8975f5c5SAndroid Build Coastguard Worker const Extensions &extensions = context->getExtensions();
4593*8975f5c5SAndroid Build Coastguard Worker
4594*8975f5c5SAndroid Build Coastguard Worker switch (mode)
4595*8975f5c5SAndroid Build Coastguard Worker {
4596*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Points:
4597*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Lines:
4598*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineLoop:
4599*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineStrip:
4600*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Triangles:
4601*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleStrip:
4602*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleFan:
4603*8975f5c5SAndroid Build Coastguard Worker break;
4604*8975f5c5SAndroid Build Coastguard Worker
4605*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LinesAdjacency:
4606*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::LineStripAdjacency:
4607*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TrianglesAdjacency:
4608*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::TriangleStripAdjacency:
4609*8975f5c5SAndroid Build Coastguard Worker if (!extensions.geometryShaderAny() && context->getClientVersion() < ES_3_2)
4610*8975f5c5SAndroid Build Coastguard Worker {
4611*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
4612*8975f5c5SAndroid Build Coastguard Worker return;
4613*8975f5c5SAndroid Build Coastguard Worker }
4614*8975f5c5SAndroid Build Coastguard Worker break;
4615*8975f5c5SAndroid Build Coastguard Worker
4616*8975f5c5SAndroid Build Coastguard Worker case PrimitiveMode::Patches:
4617*8975f5c5SAndroid Build Coastguard Worker if (!extensions.tessellationShaderAny() && context->getClientVersion() < ES_3_2)
4618*8975f5c5SAndroid Build Coastguard Worker {
4619*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTessellationShaderEXTNotEnabled);
4620*8975f5c5SAndroid Build Coastguard Worker return;
4621*8975f5c5SAndroid Build Coastguard Worker }
4622*8975f5c5SAndroid Build Coastguard Worker break;
4623*8975f5c5SAndroid Build Coastguard Worker
4624*8975f5c5SAndroid Build Coastguard Worker default:
4625*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDrawMode);
4626*8975f5c5SAndroid Build Coastguard Worker return;
4627*8975f5c5SAndroid Build Coastguard Worker }
4628*8975f5c5SAndroid Build Coastguard Worker
4629*8975f5c5SAndroid Build Coastguard Worker // If we are running GLES1, there is no current program.
4630*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() >= Version(2, 0))
4631*8975f5c5SAndroid Build Coastguard Worker {
4632*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *executable = state.getProgramExecutable();
4633*8975f5c5SAndroid Build Coastguard Worker ASSERT(executable);
4634*8975f5c5SAndroid Build Coastguard Worker
4635*8975f5c5SAndroid Build Coastguard Worker // Do geometry shader specific validations
4636*8975f5c5SAndroid Build Coastguard Worker if (executable->hasLinkedShaderStage(ShaderType::Geometry))
4637*8975f5c5SAndroid Build Coastguard Worker {
4638*8975f5c5SAndroid Build Coastguard Worker if (!IsCompatibleDrawModeWithGeometryShader(
4639*8975f5c5SAndroid Build Coastguard Worker mode, executable->getGeometryShaderInputPrimitiveType()))
4640*8975f5c5SAndroid Build Coastguard Worker {
4641*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
4642*8975f5c5SAndroid Build Coastguard Worker kIncompatibleDrawModeAgainstGeometryShader);
4643*8975f5c5SAndroid Build Coastguard Worker return;
4644*8975f5c5SAndroid Build Coastguard Worker }
4645*8975f5c5SAndroid Build Coastguard Worker }
4646*8975f5c5SAndroid Build Coastguard Worker
4647*8975f5c5SAndroid Build Coastguard Worker if (executable->hasLinkedTessellationShader() && mode != PrimitiveMode::Patches)
4648*8975f5c5SAndroid Build Coastguard Worker {
4649*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
4650*8975f5c5SAndroid Build Coastguard Worker kIncompatibleDrawModeWithTessellationShader);
4651*8975f5c5SAndroid Build Coastguard Worker return;
4652*8975f5c5SAndroid Build Coastguard Worker }
4653*8975f5c5SAndroid Build Coastguard Worker
4654*8975f5c5SAndroid Build Coastguard Worker if (!executable->hasLinkedTessellationShader() && mode == PrimitiveMode::Patches)
4655*8975f5c5SAndroid Build Coastguard Worker {
4656*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
4657*8975f5c5SAndroid Build Coastguard Worker kIncompatibleDrawModeWithoutTessellationShader);
4658*8975f5c5SAndroid Build Coastguard Worker return;
4659*8975f5c5SAndroid Build Coastguard Worker }
4660*8975f5c5SAndroid Build Coastguard Worker }
4661*8975f5c5SAndroid Build Coastguard Worker
4662*8975f5c5SAndroid Build Coastguard Worker // An error should be recorded.
4663*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
4664*8975f5c5SAndroid Build Coastguard Worker }
4665*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawArraysInstancedANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)4666*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawArraysInstancedANGLE(const Context *context,
4667*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4668*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode mode,
4669*8975f5c5SAndroid Build Coastguard Worker GLint first,
4670*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
4671*8975f5c5SAndroid Build Coastguard Worker GLsizei primcount)
4672*8975f5c5SAndroid Build Coastguard Worker {
4673*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().instancedArraysANGLE)
4674*8975f5c5SAndroid Build Coastguard Worker {
4675*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4676*8975f5c5SAndroid Build Coastguard Worker return false;
4677*8975f5c5SAndroid Build Coastguard Worker }
4678*8975f5c5SAndroid Build Coastguard Worker
4679*8975f5c5SAndroid Build Coastguard Worker if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount, 0))
4680*8975f5c5SAndroid Build Coastguard Worker {
4681*8975f5c5SAndroid Build Coastguard Worker return false;
4682*8975f5c5SAndroid Build Coastguard Worker }
4683*8975f5c5SAndroid Build Coastguard Worker
4684*8975f5c5SAndroid Build Coastguard Worker return ValidateDrawInstancedANGLE(context, entryPoint);
4685*8975f5c5SAndroid Build Coastguard Worker }
4686*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawArraysInstancedEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)4687*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawArraysInstancedEXT(const Context *context,
4688*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4689*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode mode,
4690*8975f5c5SAndroid Build Coastguard Worker GLint first,
4691*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
4692*8975f5c5SAndroid Build Coastguard Worker GLsizei primcount)
4693*8975f5c5SAndroid Build Coastguard Worker {
4694*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().instancedArraysEXT)
4695*8975f5c5SAndroid Build Coastguard Worker {
4696*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4697*8975f5c5SAndroid Build Coastguard Worker return false;
4698*8975f5c5SAndroid Build Coastguard Worker }
4699*8975f5c5SAndroid Build Coastguard Worker
4700*8975f5c5SAndroid Build Coastguard Worker if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount, 0))
4701*8975f5c5SAndroid Build Coastguard Worker {
4702*8975f5c5SAndroid Build Coastguard Worker return false;
4703*8975f5c5SAndroid Build Coastguard Worker }
4704*8975f5c5SAndroid Build Coastguard Worker
4705*8975f5c5SAndroid Build Coastguard Worker return true;
4706*8975f5c5SAndroid Build Coastguard Worker }
4707*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawElementsStates(const Context * context)4708*8975f5c5SAndroid Build Coastguard Worker const char *ValidateDrawElementsStates(const Context *context)
4709*8975f5c5SAndroid Build Coastguard Worker {
4710*8975f5c5SAndroid Build Coastguard Worker const State &state = context->getState();
4711*8975f5c5SAndroid Build Coastguard Worker
4712*8975f5c5SAndroid Build Coastguard Worker if (context->getStateCache().isTransformFeedbackActiveUnpaused())
4713*8975f5c5SAndroid Build Coastguard Worker {
4714*8975f5c5SAndroid Build Coastguard Worker // EXT_geometry_shader allows transform feedback to work with all draw commands.
4715*8975f5c5SAndroid Build Coastguard Worker // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
4716*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().geometryShaderAny() && context->getClientVersion() < ES_3_2)
4717*8975f5c5SAndroid Build Coastguard Worker {
4718*8975f5c5SAndroid Build Coastguard Worker // It is an invalid operation to call DrawElements, DrawRangeElements or
4719*8975f5c5SAndroid Build Coastguard Worker // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
4720*8975f5c5SAndroid Build Coastguard Worker // 86)
4721*8975f5c5SAndroid Build Coastguard Worker return kUnsupportedDrawModeForTransformFeedback;
4722*8975f5c5SAndroid Build Coastguard Worker }
4723*8975f5c5SAndroid Build Coastguard Worker }
4724*8975f5c5SAndroid Build Coastguard Worker
4725*8975f5c5SAndroid Build Coastguard Worker const VertexArray *vao = state.getVertexArray();
4726*8975f5c5SAndroid Build Coastguard Worker Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
4727*8975f5c5SAndroid Build Coastguard Worker
4728*8975f5c5SAndroid Build Coastguard Worker if (elementArrayBuffer)
4729*8975f5c5SAndroid Build Coastguard Worker {
4730*8975f5c5SAndroid Build Coastguard Worker if (elementArrayBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
4731*8975f5c5SAndroid Build Coastguard Worker {
4732*8975f5c5SAndroid Build Coastguard Worker return kElementArrayBufferBoundForTransformFeedback;
4733*8975f5c5SAndroid Build Coastguard Worker }
4734*8975f5c5SAndroid Build Coastguard Worker if (elementArrayBuffer->isMapped() &&
4735*8975f5c5SAndroid Build Coastguard Worker (!elementArrayBuffer->isImmutable() ||
4736*8975f5c5SAndroid Build Coastguard Worker (elementArrayBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) == 0))
4737*8975f5c5SAndroid Build Coastguard Worker {
4738*8975f5c5SAndroid Build Coastguard Worker return kBufferMapped;
4739*8975f5c5SAndroid Build Coastguard Worker }
4740*8975f5c5SAndroid Build Coastguard Worker }
4741*8975f5c5SAndroid Build Coastguard Worker else
4742*8975f5c5SAndroid Build Coastguard Worker {
4743*8975f5c5SAndroid Build Coastguard Worker // [WebGL 1.0] Section 6.2 No Client Side Arrays
4744*8975f5c5SAndroid Build Coastguard Worker // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
4745*8975f5c5SAndroid Build Coastguard Worker // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
4746*8975f5c5SAndroid Build Coastguard Worker if (!context->getState().areClientArraysEnabled() || context->isWebGL())
4747*8975f5c5SAndroid Build Coastguard Worker {
4748*8975f5c5SAndroid Build Coastguard Worker return kMustHaveElementArrayBinding;
4749*8975f5c5SAndroid Build Coastguard Worker }
4750*8975f5c5SAndroid Build Coastguard Worker }
4751*8975f5c5SAndroid Build Coastguard Worker
4752*8975f5c5SAndroid Build Coastguard Worker return nullptr;
4753*8975f5c5SAndroid Build Coastguard Worker }
4754*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawElementsInstancedANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount)4755*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawElementsInstancedANGLE(const Context *context,
4756*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4757*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode mode,
4758*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
4759*8975f5c5SAndroid Build Coastguard Worker DrawElementsType type,
4760*8975f5c5SAndroid Build Coastguard Worker const void *indices,
4761*8975f5c5SAndroid Build Coastguard Worker GLsizei primcount)
4762*8975f5c5SAndroid Build Coastguard Worker {
4763*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().instancedArraysANGLE)
4764*8975f5c5SAndroid Build Coastguard Worker {
4765*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4766*8975f5c5SAndroid Build Coastguard Worker return false;
4767*8975f5c5SAndroid Build Coastguard Worker }
4768*8975f5c5SAndroid Build Coastguard Worker
4769*8975f5c5SAndroid Build Coastguard Worker if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
4770*8975f5c5SAndroid Build Coastguard Worker primcount, 0))
4771*8975f5c5SAndroid Build Coastguard Worker {
4772*8975f5c5SAndroid Build Coastguard Worker return false;
4773*8975f5c5SAndroid Build Coastguard Worker }
4774*8975f5c5SAndroid Build Coastguard Worker
4775*8975f5c5SAndroid Build Coastguard Worker return ValidateDrawInstancedANGLE(context, entryPoint);
4776*8975f5c5SAndroid Build Coastguard Worker }
4777*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawElementsInstancedEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount)4778*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawElementsInstancedEXT(const Context *context,
4779*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4780*8975f5c5SAndroid Build Coastguard Worker PrimitiveMode mode,
4781*8975f5c5SAndroid Build Coastguard Worker GLsizei count,
4782*8975f5c5SAndroid Build Coastguard Worker DrawElementsType type,
4783*8975f5c5SAndroid Build Coastguard Worker const void *indices,
4784*8975f5c5SAndroid Build Coastguard Worker GLsizei primcount)
4785*8975f5c5SAndroid Build Coastguard Worker {
4786*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().instancedArraysEXT)
4787*8975f5c5SAndroid Build Coastguard Worker {
4788*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4789*8975f5c5SAndroid Build Coastguard Worker return false;
4790*8975f5c5SAndroid Build Coastguard Worker }
4791*8975f5c5SAndroid Build Coastguard Worker
4792*8975f5c5SAndroid Build Coastguard Worker if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
4793*8975f5c5SAndroid Build Coastguard Worker primcount, 0))
4794*8975f5c5SAndroid Build Coastguard Worker {
4795*8975f5c5SAndroid Build Coastguard Worker return false;
4796*8975f5c5SAndroid Build Coastguard Worker }
4797*8975f5c5SAndroid Build Coastguard Worker
4798*8975f5c5SAndroid Build Coastguard Worker return true;
4799*8975f5c5SAndroid Build Coastguard Worker }
4800*8975f5c5SAndroid Build Coastguard Worker
ValidateGetUniformBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location)4801*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformBase(const Context *context,
4802*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4803*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4804*8975f5c5SAndroid Build Coastguard Worker UniformLocation location)
4805*8975f5c5SAndroid Build Coastguard Worker {
4806*8975f5c5SAndroid Build Coastguard Worker if (program.value == 0)
4807*8975f5c5SAndroid Build Coastguard Worker {
4808*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
4809*8975f5c5SAndroid Build Coastguard Worker return false;
4810*8975f5c5SAndroid Build Coastguard Worker }
4811*8975f5c5SAndroid Build Coastguard Worker
4812*8975f5c5SAndroid Build Coastguard Worker Program *programObject = GetValidProgram(context, entryPoint, program);
4813*8975f5c5SAndroid Build Coastguard Worker if (!programObject)
4814*8975f5c5SAndroid Build Coastguard Worker {
4815*8975f5c5SAndroid Build Coastguard Worker return false;
4816*8975f5c5SAndroid Build Coastguard Worker }
4817*8975f5c5SAndroid Build Coastguard Worker
4818*8975f5c5SAndroid Build Coastguard Worker if (!programObject || !programObject->isLinked())
4819*8975f5c5SAndroid Build Coastguard Worker {
4820*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
4821*8975f5c5SAndroid Build Coastguard Worker return false;
4822*8975f5c5SAndroid Build Coastguard Worker }
4823*8975f5c5SAndroid Build Coastguard Worker
4824*8975f5c5SAndroid Build Coastguard Worker if (!programObject->getExecutable().isValidUniformLocation(location))
4825*8975f5c5SAndroid Build Coastguard Worker {
4826*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformLocation);
4827*8975f5c5SAndroid Build Coastguard Worker return false;
4828*8975f5c5SAndroid Build Coastguard Worker }
4829*8975f5c5SAndroid Build Coastguard Worker
4830*8975f5c5SAndroid Build Coastguard Worker return true;
4831*8975f5c5SAndroid Build Coastguard Worker }
4832*8975f5c5SAndroid Build Coastguard Worker
ValidateSizedGetUniform(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length)4833*8975f5c5SAndroid Build Coastguard Worker bool ValidateSizedGetUniform(const Context *context,
4834*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4835*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4836*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4837*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4838*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
4839*8975f5c5SAndroid Build Coastguard Worker {
4840*8975f5c5SAndroid Build Coastguard Worker if (length)
4841*8975f5c5SAndroid Build Coastguard Worker {
4842*8975f5c5SAndroid Build Coastguard Worker *length = 0;
4843*8975f5c5SAndroid Build Coastguard Worker }
4844*8975f5c5SAndroid Build Coastguard Worker
4845*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetUniformBase(context, entryPoint, program, location))
4846*8975f5c5SAndroid Build Coastguard Worker {
4847*8975f5c5SAndroid Build Coastguard Worker return false;
4848*8975f5c5SAndroid Build Coastguard Worker }
4849*8975f5c5SAndroid Build Coastguard Worker
4850*8975f5c5SAndroid Build Coastguard Worker if (bufSize < 0)
4851*8975f5c5SAndroid Build Coastguard Worker {
4852*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNegativeBufferSize);
4853*8975f5c5SAndroid Build Coastguard Worker return false;
4854*8975f5c5SAndroid Build Coastguard Worker }
4855*8975f5c5SAndroid Build Coastguard Worker
4856*8975f5c5SAndroid Build Coastguard Worker Program *programObject = context->getProgramResolveLink(program);
4857*8975f5c5SAndroid Build Coastguard Worker ASSERT(programObject);
4858*8975f5c5SAndroid Build Coastguard Worker
4859*8975f5c5SAndroid Build Coastguard Worker // sized queries -- ensure the provided buffer is large enough
4860*8975f5c5SAndroid Build Coastguard Worker const LinkedUniform &uniform = programObject->getExecutable().getUniformByLocation(location);
4861*8975f5c5SAndroid Build Coastguard Worker size_t requiredBytes = VariableExternalSize(uniform.getType());
4862*8975f5c5SAndroid Build Coastguard Worker if (static_cast<size_t>(bufSize) < requiredBytes)
4863*8975f5c5SAndroid Build Coastguard Worker {
4864*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
4865*8975f5c5SAndroid Build Coastguard Worker return false;
4866*8975f5c5SAndroid Build Coastguard Worker }
4867*8975f5c5SAndroid Build Coastguard Worker
4868*8975f5c5SAndroid Build Coastguard Worker if (length)
4869*8975f5c5SAndroid Build Coastguard Worker {
4870*8975f5c5SAndroid Build Coastguard Worker *length = VariableComponentCount(uniform.getType());
4871*8975f5c5SAndroid Build Coastguard Worker }
4872*8975f5c5SAndroid Build Coastguard Worker return true;
4873*8975f5c5SAndroid Build Coastguard Worker }
4874*8975f5c5SAndroid Build Coastguard Worker
ValidateGetnUniformfvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLfloat * params)4875*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformfvEXT(const Context *context,
4876*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4877*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4878*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4879*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4880*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
4881*8975f5c5SAndroid Build Coastguard Worker {
4882*8975f5c5SAndroid Build Coastguard Worker return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
4883*8975f5c5SAndroid Build Coastguard Worker }
4884*8975f5c5SAndroid Build Coastguard Worker
ValidateGetnUniformfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLfloat * params)4885*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformfvRobustANGLE(const Context *context,
4886*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4887*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4888*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4889*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4890*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
4891*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
4892*8975f5c5SAndroid Build Coastguard Worker {
4893*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
4894*8975f5c5SAndroid Build Coastguard Worker return false;
4895*8975f5c5SAndroid Build Coastguard Worker }
4896*8975f5c5SAndroid Build Coastguard Worker
ValidateGetnUniformivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLint * params)4897*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformivEXT(const Context *context,
4898*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4899*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4900*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4901*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4902*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
4903*8975f5c5SAndroid Build Coastguard Worker {
4904*8975f5c5SAndroid Build Coastguard Worker return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
4905*8975f5c5SAndroid Build Coastguard Worker }
4906*8975f5c5SAndroid Build Coastguard Worker
ValidateGetnUniformivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLint * params)4907*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformivRobustANGLE(const Context *context,
4908*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4909*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4910*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4911*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4912*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
4913*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
4914*8975f5c5SAndroid Build Coastguard Worker {
4915*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
4916*8975f5c5SAndroid Build Coastguard Worker return false;
4917*8975f5c5SAndroid Build Coastguard Worker }
4918*8975f5c5SAndroid Build Coastguard Worker
ValidateGetnUniformuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLuint * params)4919*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformuivRobustANGLE(const Context *context,
4920*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4921*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4922*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4923*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4924*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
4925*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
4926*8975f5c5SAndroid Build Coastguard Worker {
4927*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
4928*8975f5c5SAndroid Build Coastguard Worker return false;
4929*8975f5c5SAndroid Build Coastguard Worker }
4930*8975f5c5SAndroid Build Coastguard Worker
ValidateGetUniformfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLfloat * params)4931*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformfvRobustANGLE(const Context *context,
4932*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4933*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4934*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4935*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4936*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
4937*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
4938*8975f5c5SAndroid Build Coastguard Worker {
4939*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
4940*8975f5c5SAndroid Build Coastguard Worker {
4941*8975f5c5SAndroid Build Coastguard Worker return false;
4942*8975f5c5SAndroid Build Coastguard Worker }
4943*8975f5c5SAndroid Build Coastguard Worker
4944*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
4945*8975f5c5SAndroid Build Coastguard Worker
4946*8975f5c5SAndroid Build Coastguard Worker // bufSize is validated in ValidateSizedGetUniform
4947*8975f5c5SAndroid Build Coastguard Worker if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
4948*8975f5c5SAndroid Build Coastguard Worker {
4949*8975f5c5SAndroid Build Coastguard Worker return false;
4950*8975f5c5SAndroid Build Coastguard Worker }
4951*8975f5c5SAndroid Build Coastguard Worker
4952*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
4953*8975f5c5SAndroid Build Coastguard Worker
4954*8975f5c5SAndroid Build Coastguard Worker return true;
4955*8975f5c5SAndroid Build Coastguard Worker }
4956*8975f5c5SAndroid Build Coastguard Worker
ValidateGetUniformivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLint * params)4957*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformivRobustANGLE(const Context *context,
4958*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4959*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4960*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4961*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4962*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
4963*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
4964*8975f5c5SAndroid Build Coastguard Worker {
4965*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
4966*8975f5c5SAndroid Build Coastguard Worker {
4967*8975f5c5SAndroid Build Coastguard Worker return false;
4968*8975f5c5SAndroid Build Coastguard Worker }
4969*8975f5c5SAndroid Build Coastguard Worker
4970*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
4971*8975f5c5SAndroid Build Coastguard Worker
4972*8975f5c5SAndroid Build Coastguard Worker // bufSize is validated in ValidateSizedGetUniform
4973*8975f5c5SAndroid Build Coastguard Worker if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
4974*8975f5c5SAndroid Build Coastguard Worker {
4975*8975f5c5SAndroid Build Coastguard Worker return false;
4976*8975f5c5SAndroid Build Coastguard Worker }
4977*8975f5c5SAndroid Build Coastguard Worker
4978*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
4979*8975f5c5SAndroid Build Coastguard Worker
4980*8975f5c5SAndroid Build Coastguard Worker return true;
4981*8975f5c5SAndroid Build Coastguard Worker }
4982*8975f5c5SAndroid Build Coastguard Worker
ValidateGetUniformuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLuint * params)4983*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformuivRobustANGLE(const Context *context,
4984*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
4985*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
4986*8975f5c5SAndroid Build Coastguard Worker UniformLocation location,
4987*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
4988*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
4989*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
4990*8975f5c5SAndroid Build Coastguard Worker {
4991*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
4992*8975f5c5SAndroid Build Coastguard Worker {
4993*8975f5c5SAndroid Build Coastguard Worker return false;
4994*8975f5c5SAndroid Build Coastguard Worker }
4995*8975f5c5SAndroid Build Coastguard Worker
4996*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
4997*8975f5c5SAndroid Build Coastguard Worker {
4998*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4999*8975f5c5SAndroid Build Coastguard Worker return false;
5000*8975f5c5SAndroid Build Coastguard Worker }
5001*8975f5c5SAndroid Build Coastguard Worker
5002*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
5003*8975f5c5SAndroid Build Coastguard Worker
5004*8975f5c5SAndroid Build Coastguard Worker // bufSize is validated in ValidateSizedGetUniform
5005*8975f5c5SAndroid Build Coastguard Worker if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
5006*8975f5c5SAndroid Build Coastguard Worker {
5007*8975f5c5SAndroid Build Coastguard Worker return false;
5008*8975f5c5SAndroid Build Coastguard Worker }
5009*8975f5c5SAndroid Build Coastguard Worker
5010*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
5011*8975f5c5SAndroid Build Coastguard Worker
5012*8975f5c5SAndroid Build Coastguard Worker return true;
5013*8975f5c5SAndroid Build Coastguard Worker }
5014*8975f5c5SAndroid Build Coastguard Worker
ValidateDiscardFramebufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei numAttachments,const GLenum * attachments,bool defaultFramebuffer)5015*8975f5c5SAndroid Build Coastguard Worker bool ValidateDiscardFramebufferBase(const Context *context,
5016*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5017*8975f5c5SAndroid Build Coastguard Worker GLenum target,
5018*8975f5c5SAndroid Build Coastguard Worker GLsizei numAttachments,
5019*8975f5c5SAndroid Build Coastguard Worker const GLenum *attachments,
5020*8975f5c5SAndroid Build Coastguard Worker bool defaultFramebuffer)
5021*8975f5c5SAndroid Build Coastguard Worker {
5022*8975f5c5SAndroid Build Coastguard Worker if (numAttachments < 0)
5023*8975f5c5SAndroid Build Coastguard Worker {
5024*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeAttachments);
5025*8975f5c5SAndroid Build Coastguard Worker return false;
5026*8975f5c5SAndroid Build Coastguard Worker }
5027*8975f5c5SAndroid Build Coastguard Worker
5028*8975f5c5SAndroid Build Coastguard Worker for (GLsizei i = 0; i < numAttachments; ++i)
5029*8975f5c5SAndroid Build Coastguard Worker {
5030*8975f5c5SAndroid Build Coastguard Worker if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
5031*8975f5c5SAndroid Build Coastguard Worker {
5032*8975f5c5SAndroid Build Coastguard Worker if (defaultFramebuffer)
5033*8975f5c5SAndroid Build Coastguard Worker {
5034*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
5035*8975f5c5SAndroid Build Coastguard Worker return false;
5036*8975f5c5SAndroid Build Coastguard Worker }
5037*8975f5c5SAndroid Build Coastguard Worker
5038*8975f5c5SAndroid Build Coastguard Worker if (attachments[i] >=
5039*8975f5c5SAndroid Build Coastguard Worker GL_COLOR_ATTACHMENT0 + static_cast<GLuint>(context->getCaps().maxColorAttachments))
5040*8975f5c5SAndroid Build Coastguard Worker {
5041*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
5042*8975f5c5SAndroid Build Coastguard Worker return false;
5043*8975f5c5SAndroid Build Coastguard Worker }
5044*8975f5c5SAndroid Build Coastguard Worker }
5045*8975f5c5SAndroid Build Coastguard Worker else
5046*8975f5c5SAndroid Build Coastguard Worker {
5047*8975f5c5SAndroid Build Coastguard Worker switch (attachments[i])
5048*8975f5c5SAndroid Build Coastguard Worker {
5049*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
5050*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
5051*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
5052*8975f5c5SAndroid Build Coastguard Worker if (defaultFramebuffer)
5053*8975f5c5SAndroid Build Coastguard Worker {
5054*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
5055*8975f5c5SAndroid Build Coastguard Worker kDefaultFramebufferInvalidAttachment);
5056*8975f5c5SAndroid Build Coastguard Worker return false;
5057*8975f5c5SAndroid Build Coastguard Worker }
5058*8975f5c5SAndroid Build Coastguard Worker break;
5059*8975f5c5SAndroid Build Coastguard Worker case GL_COLOR:
5060*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH:
5061*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL:
5062*8975f5c5SAndroid Build Coastguard Worker if (!defaultFramebuffer)
5063*8975f5c5SAndroid Build Coastguard Worker {
5064*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
5065*8975f5c5SAndroid Build Coastguard Worker kDefaultFramebufferAttachmentOnUserFBO);
5066*8975f5c5SAndroid Build Coastguard Worker return false;
5067*8975f5c5SAndroid Build Coastguard Worker }
5068*8975f5c5SAndroid Build Coastguard Worker break;
5069*8975f5c5SAndroid Build Coastguard Worker default:
5070*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5071*8975f5c5SAndroid Build Coastguard Worker return false;
5072*8975f5c5SAndroid Build Coastguard Worker }
5073*8975f5c5SAndroid Build Coastguard Worker }
5074*8975f5c5SAndroid Build Coastguard Worker }
5075*8975f5c5SAndroid Build Coastguard Worker
5076*8975f5c5SAndroid Build Coastguard Worker return true;
5077*8975f5c5SAndroid Build Coastguard Worker }
5078*8975f5c5SAndroid Build Coastguard Worker
ValidateInsertEventMarkerEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei length,const char * marker)5079*8975f5c5SAndroid Build Coastguard Worker bool ValidateInsertEventMarkerEXT(const Context *context,
5080*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5081*8975f5c5SAndroid Build Coastguard Worker GLsizei length,
5082*8975f5c5SAndroid Build Coastguard Worker const char *marker)
5083*8975f5c5SAndroid Build Coastguard Worker {
5084*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().debugMarkerEXT)
5085*8975f5c5SAndroid Build Coastguard Worker {
5086*8975f5c5SAndroid Build Coastguard Worker // The debug marker calls should not set error state
5087*8975f5c5SAndroid Build Coastguard Worker // However, it seems reasonable to set an error state if the extension is not enabled
5088*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5089*8975f5c5SAndroid Build Coastguard Worker return false;
5090*8975f5c5SAndroid Build Coastguard Worker }
5091*8975f5c5SAndroid Build Coastguard Worker
5092*8975f5c5SAndroid Build Coastguard Worker // Note that debug marker calls must not set error state
5093*8975f5c5SAndroid Build Coastguard Worker if (length < 0)
5094*8975f5c5SAndroid Build Coastguard Worker {
5095*8975f5c5SAndroid Build Coastguard Worker return false;
5096*8975f5c5SAndroid Build Coastguard Worker }
5097*8975f5c5SAndroid Build Coastguard Worker
5098*8975f5c5SAndroid Build Coastguard Worker if (marker == nullptr)
5099*8975f5c5SAndroid Build Coastguard Worker {
5100*8975f5c5SAndroid Build Coastguard Worker return false;
5101*8975f5c5SAndroid Build Coastguard Worker }
5102*8975f5c5SAndroid Build Coastguard Worker
5103*8975f5c5SAndroid Build Coastguard Worker return true;
5104*8975f5c5SAndroid Build Coastguard Worker }
5105*8975f5c5SAndroid Build Coastguard Worker
ValidatePushGroupMarkerEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei length,const char * marker)5106*8975f5c5SAndroid Build Coastguard Worker bool ValidatePushGroupMarkerEXT(const Context *context,
5107*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5108*8975f5c5SAndroid Build Coastguard Worker GLsizei length,
5109*8975f5c5SAndroid Build Coastguard Worker const char *marker)
5110*8975f5c5SAndroid Build Coastguard Worker {
5111*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().debugMarkerEXT)
5112*8975f5c5SAndroid Build Coastguard Worker {
5113*8975f5c5SAndroid Build Coastguard Worker // The debug marker calls should not set error state
5114*8975f5c5SAndroid Build Coastguard Worker // However, it seems reasonable to set an error state if the extension is not enabled
5115*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5116*8975f5c5SAndroid Build Coastguard Worker return false;
5117*8975f5c5SAndroid Build Coastguard Worker }
5118*8975f5c5SAndroid Build Coastguard Worker
5119*8975f5c5SAndroid Build Coastguard Worker // Note that debug marker calls must not set error state
5120*8975f5c5SAndroid Build Coastguard Worker if (length < 0)
5121*8975f5c5SAndroid Build Coastguard Worker {
5122*8975f5c5SAndroid Build Coastguard Worker return false;
5123*8975f5c5SAndroid Build Coastguard Worker }
5124*8975f5c5SAndroid Build Coastguard Worker
5125*8975f5c5SAndroid Build Coastguard Worker if (length > 0 && marker == nullptr)
5126*8975f5c5SAndroid Build Coastguard Worker {
5127*8975f5c5SAndroid Build Coastguard Worker return false;
5128*8975f5c5SAndroid Build Coastguard Worker }
5129*8975f5c5SAndroid Build Coastguard Worker
5130*8975f5c5SAndroid Build Coastguard Worker return true;
5131*8975f5c5SAndroid Build Coastguard Worker }
5132*8975f5c5SAndroid Build Coastguard Worker
ValidateEGLImageObject(const Context * context,angle::EntryPoint entryPoint,TextureType type,egl::ImageID imageID)5133*8975f5c5SAndroid Build Coastguard Worker bool ValidateEGLImageObject(const Context *context,
5134*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5135*8975f5c5SAndroid Build Coastguard Worker TextureType type,
5136*8975f5c5SAndroid Build Coastguard Worker egl::ImageID imageID)
5137*8975f5c5SAndroid Build Coastguard Worker {
5138*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getDisplay());
5139*8975f5c5SAndroid Build Coastguard Worker if (!context->getDisplay()->isValidImage(imageID))
5140*8975f5c5SAndroid Build Coastguard Worker {
5141*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidEGLImage);
5142*8975f5c5SAndroid Build Coastguard Worker return false;
5143*8975f5c5SAndroid Build Coastguard Worker }
5144*8975f5c5SAndroid Build Coastguard Worker
5145*8975f5c5SAndroid Build Coastguard Worker egl::Image *imageObject = context->getDisplay()->getImage(imageID);
5146*8975f5c5SAndroid Build Coastguard Worker if (imageObject->getSamples() > 0)
5147*8975f5c5SAndroid Build Coastguard Worker {
5148*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageCannotCreate2DMultisampled);
5149*8975f5c5SAndroid Build Coastguard Worker return false;
5150*8975f5c5SAndroid Build Coastguard Worker }
5151*8975f5c5SAndroid Build Coastguard Worker
5152*8975f5c5SAndroid Build Coastguard Worker if (!imageObject->isTexturable(context))
5153*8975f5c5SAndroid Build Coastguard Worker {
5154*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureFormatNotSupported);
5155*8975f5c5SAndroid Build Coastguard Worker return false;
5156*8975f5c5SAndroid Build Coastguard Worker }
5157*8975f5c5SAndroid Build Coastguard Worker
5158*8975f5c5SAndroid Build Coastguard Worker // Validate source egl image and target texture are compatible
5159*8975f5c5SAndroid Build Coastguard Worker size_t depth = static_cast<size_t>(imageObject->getExtents().depth);
5160*8975f5c5SAndroid Build Coastguard Worker if (imageObject->isYUV() && type != TextureType::External)
5161*8975f5c5SAndroid Build Coastguard Worker {
5162*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5163*8975f5c5SAndroid Build Coastguard Worker "Image is YUV, target must be TEXTURE_EXTERNAL_OES");
5164*8975f5c5SAndroid Build Coastguard Worker return false;
5165*8975f5c5SAndroid Build Coastguard Worker }
5166*8975f5c5SAndroid Build Coastguard Worker
5167*8975f5c5SAndroid Build Coastguard Worker if (depth > 1 && type != TextureType::_2DArray && type != TextureType::CubeMap &&
5168*8975f5c5SAndroid Build Coastguard Worker type != TextureType::CubeMapArray && type != TextureType::_3D)
5169*8975f5c5SAndroid Build Coastguard Worker {
5170*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5171*8975f5c5SAndroid Build Coastguard Worker return false;
5172*8975f5c5SAndroid Build Coastguard Worker }
5173*8975f5c5SAndroid Build Coastguard Worker
5174*8975f5c5SAndroid Build Coastguard Worker if (imageObject->isCubeMap() && type != TextureType::CubeMapArray &&
5175*8975f5c5SAndroid Build Coastguard Worker (type != TextureType::CubeMap || depth > gl::kCubeFaceCount))
5176*8975f5c5SAndroid Build Coastguard Worker {
5177*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5178*8975f5c5SAndroid Build Coastguard Worker return false;
5179*8975f5c5SAndroid Build Coastguard Worker }
5180*8975f5c5SAndroid Build Coastguard Worker
5181*8975f5c5SAndroid Build Coastguard Worker if (imageObject->getLevelCount() > 1 && type == TextureType::External)
5182*8975f5c5SAndroid Build Coastguard Worker {
5183*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5184*8975f5c5SAndroid Build Coastguard Worker return false;
5185*8975f5c5SAndroid Build Coastguard Worker }
5186*8975f5c5SAndroid Build Coastguard Worker
5187*8975f5c5SAndroid Build Coastguard Worker // 3d EGLImages are currently not supported
5188*8975f5c5SAndroid Build Coastguard Worker if (type == TextureType::_3D)
5189*8975f5c5SAndroid Build Coastguard Worker {
5190*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5191*8975f5c5SAndroid Build Coastguard Worker return false;
5192*8975f5c5SAndroid Build Coastguard Worker }
5193*8975f5c5SAndroid Build Coastguard Worker
5194*8975f5c5SAndroid Build Coastguard Worker if (imageObject->hasProtectedContent() && !context->getState().hasProtectedContent())
5195*8975f5c5SAndroid Build Coastguard Worker {
5196*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5197*8975f5c5SAndroid Build Coastguard Worker "Mismatch between Image and Context Protected Content state");
5198*8975f5c5SAndroid Build Coastguard Worker return false;
5199*8975f5c5SAndroid Build Coastguard Worker }
5200*8975f5c5SAndroid Build Coastguard Worker
5201*8975f5c5SAndroid Build Coastguard Worker return true;
5202*8975f5c5SAndroid Build Coastguard Worker }
5203*8975f5c5SAndroid Build Coastguard Worker
ValidateEGLImageTargetTexture2DOES(const Context * context,angle::EntryPoint entryPoint,TextureType type,egl::ImageID image)5204*8975f5c5SAndroid Build Coastguard Worker bool ValidateEGLImageTargetTexture2DOES(const Context *context,
5205*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5206*8975f5c5SAndroid Build Coastguard Worker TextureType type,
5207*8975f5c5SAndroid Build Coastguard Worker egl::ImageID image)
5208*8975f5c5SAndroid Build Coastguard Worker {
5209*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().EGLImageOES && !context->getExtensions().EGLImageExternalOES)
5210*8975f5c5SAndroid Build Coastguard Worker {
5211*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5212*8975f5c5SAndroid Build Coastguard Worker return false;
5213*8975f5c5SAndroid Build Coastguard Worker }
5214*8975f5c5SAndroid Build Coastguard Worker
5215*8975f5c5SAndroid Build Coastguard Worker switch (type)
5216*8975f5c5SAndroid Build Coastguard Worker {
5217*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2D:
5218*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().EGLImageOES)
5219*8975f5c5SAndroid Build Coastguard Worker {
5220*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(type));
5221*8975f5c5SAndroid Build Coastguard Worker }
5222*8975f5c5SAndroid Build Coastguard Worker break;
5223*8975f5c5SAndroid Build Coastguard Worker
5224*8975f5c5SAndroid Build Coastguard Worker case TextureType::_2DArray:
5225*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().EGLImageArrayEXT)
5226*8975f5c5SAndroid Build Coastguard Worker {
5227*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(type));
5228*8975f5c5SAndroid Build Coastguard Worker }
5229*8975f5c5SAndroid Build Coastguard Worker break;
5230*8975f5c5SAndroid Build Coastguard Worker
5231*8975f5c5SAndroid Build Coastguard Worker case TextureType::External:
5232*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().EGLImageExternalOES)
5233*8975f5c5SAndroid Build Coastguard Worker {
5234*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(type));
5235*8975f5c5SAndroid Build Coastguard Worker }
5236*8975f5c5SAndroid Build Coastguard Worker break;
5237*8975f5c5SAndroid Build Coastguard Worker
5238*8975f5c5SAndroid Build Coastguard Worker default:
5239*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
5240*8975f5c5SAndroid Build Coastguard Worker return false;
5241*8975f5c5SAndroid Build Coastguard Worker }
5242*8975f5c5SAndroid Build Coastguard Worker
5243*8975f5c5SAndroid Build Coastguard Worker return ValidateEGLImageObject(context, entryPoint, type, image);
5244*8975f5c5SAndroid Build Coastguard Worker }
5245*8975f5c5SAndroid Build Coastguard Worker
ValidateEGLImageTargetRenderbufferStorageOES(const Context * context,angle::EntryPoint entryPoint,GLenum target,egl::ImageID image)5246*8975f5c5SAndroid Build Coastguard Worker bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
5247*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5248*8975f5c5SAndroid Build Coastguard Worker GLenum target,
5249*8975f5c5SAndroid Build Coastguard Worker egl::ImageID image)
5250*8975f5c5SAndroid Build Coastguard Worker {
5251*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().EGLImageOES)
5252*8975f5c5SAndroid Build Coastguard Worker {
5253*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5254*8975f5c5SAndroid Build Coastguard Worker return false;
5255*8975f5c5SAndroid Build Coastguard Worker }
5256*8975f5c5SAndroid Build Coastguard Worker
5257*8975f5c5SAndroid Build Coastguard Worker switch (target)
5258*8975f5c5SAndroid Build Coastguard Worker {
5259*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
5260*8975f5c5SAndroid Build Coastguard Worker break;
5261*8975f5c5SAndroid Build Coastguard Worker
5262*8975f5c5SAndroid Build Coastguard Worker default:
5263*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
5264*8975f5c5SAndroid Build Coastguard Worker return false;
5265*8975f5c5SAndroid Build Coastguard Worker }
5266*8975f5c5SAndroid Build Coastguard Worker
5267*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getDisplay());
5268*8975f5c5SAndroid Build Coastguard Worker if (!context->getDisplay()->isValidImage(image))
5269*8975f5c5SAndroid Build Coastguard Worker {
5270*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidEGLImage);
5271*8975f5c5SAndroid Build Coastguard Worker return false;
5272*8975f5c5SAndroid Build Coastguard Worker }
5273*8975f5c5SAndroid Build Coastguard Worker
5274*8975f5c5SAndroid Build Coastguard Worker egl::Image *imageObject = context->getDisplay()->getImage(image);
5275*8975f5c5SAndroid Build Coastguard Worker if (!imageObject->isRenderable(context))
5276*8975f5c5SAndroid Build Coastguard Worker {
5277*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageRenderbufferFormatNotSupported);
5278*8975f5c5SAndroid Build Coastguard Worker return false;
5279*8975f5c5SAndroid Build Coastguard Worker }
5280*8975f5c5SAndroid Build Coastguard Worker
5281*8975f5c5SAndroid Build Coastguard Worker if (imageObject->hasProtectedContent() != context->getState().hasProtectedContent())
5282*8975f5c5SAndroid Build Coastguard Worker {
5283*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5284*8975f5c5SAndroid Build Coastguard Worker "Mismatch between Image and Context Protected Content state");
5285*8975f5c5SAndroid Build Coastguard Worker return false;
5286*8975f5c5SAndroid Build Coastguard Worker }
5287*8975f5c5SAndroid Build Coastguard Worker
5288*8975f5c5SAndroid Build Coastguard Worker return true;
5289*8975f5c5SAndroid Build Coastguard Worker }
5290*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramBinaryBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum binaryFormat,const void * binary,GLint length)5291*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramBinaryBase(const Context *context,
5292*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5293*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
5294*8975f5c5SAndroid Build Coastguard Worker GLenum binaryFormat,
5295*8975f5c5SAndroid Build Coastguard Worker const void *binary,
5296*8975f5c5SAndroid Build Coastguard Worker GLint length)
5297*8975f5c5SAndroid Build Coastguard Worker {
5298*8975f5c5SAndroid Build Coastguard Worker Program *programObject = GetValidProgram(context, entryPoint, program);
5299*8975f5c5SAndroid Build Coastguard Worker if (programObject == nullptr)
5300*8975f5c5SAndroid Build Coastguard Worker {
5301*8975f5c5SAndroid Build Coastguard Worker return false;
5302*8975f5c5SAndroid Build Coastguard Worker }
5303*8975f5c5SAndroid Build Coastguard Worker
5304*8975f5c5SAndroid Build Coastguard Worker const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
5305*8975f5c5SAndroid Build Coastguard Worker if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
5306*8975f5c5SAndroid Build Coastguard Worker programBinaryFormats.end())
5307*8975f5c5SAndroid Build Coastguard Worker {
5308*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramBinaryFormat);
5309*8975f5c5SAndroid Build Coastguard Worker return false;
5310*8975f5c5SAndroid Build Coastguard Worker }
5311*8975f5c5SAndroid Build Coastguard Worker
5312*8975f5c5SAndroid Build Coastguard Worker if (context->hasActiveTransformFeedback(program))
5313*8975f5c5SAndroid Build Coastguard Worker {
5314*8975f5c5SAndroid Build Coastguard Worker // ES 3.0.4 section 2.15 page 91
5315*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackProgramBinary);
5316*8975f5c5SAndroid Build Coastguard Worker return false;
5317*8975f5c5SAndroid Build Coastguard Worker }
5318*8975f5c5SAndroid Build Coastguard Worker
5319*8975f5c5SAndroid Build Coastguard Worker return true;
5320*8975f5c5SAndroid Build Coastguard Worker }
5321*8975f5c5SAndroid Build Coastguard Worker
ValidateGetProgramBinaryBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei bufSize,const GLsizei * length,const GLenum * binaryFormat,const void * binary)5322*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProgramBinaryBase(const Context *context,
5323*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5324*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
5325*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
5326*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
5327*8975f5c5SAndroid Build Coastguard Worker const GLenum *binaryFormat,
5328*8975f5c5SAndroid Build Coastguard Worker const void *binary)
5329*8975f5c5SAndroid Build Coastguard Worker {
5330*8975f5c5SAndroid Build Coastguard Worker Program *programObject = GetValidProgram(context, entryPoint, program);
5331*8975f5c5SAndroid Build Coastguard Worker if (programObject == nullptr)
5332*8975f5c5SAndroid Build Coastguard Worker {
5333*8975f5c5SAndroid Build Coastguard Worker return false;
5334*8975f5c5SAndroid Build Coastguard Worker }
5335*8975f5c5SAndroid Build Coastguard Worker
5336*8975f5c5SAndroid Build Coastguard Worker if (!programObject->isLinked())
5337*8975f5c5SAndroid Build Coastguard Worker {
5338*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
5339*8975f5c5SAndroid Build Coastguard Worker return false;
5340*8975f5c5SAndroid Build Coastguard Worker }
5341*8975f5c5SAndroid Build Coastguard Worker
5342*8975f5c5SAndroid Build Coastguard Worker if (context->getCaps().programBinaryFormats.empty())
5343*8975f5c5SAndroid Build Coastguard Worker {
5344*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoProgramBinaryFormats);
5345*8975f5c5SAndroid Build Coastguard Worker return false;
5346*8975f5c5SAndroid Build Coastguard Worker }
5347*8975f5c5SAndroid Build Coastguard Worker
5348*8975f5c5SAndroid Build Coastguard Worker return true;
5349*8975f5c5SAndroid Build Coastguard Worker }
5350*8975f5c5SAndroid Build Coastguard Worker
ValidateDrawBuffersBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum * bufs)5351*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawBuffersBase(const Context *context,
5352*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5353*8975f5c5SAndroid Build Coastguard Worker GLsizei n,
5354*8975f5c5SAndroid Build Coastguard Worker const GLenum *bufs)
5355*8975f5c5SAndroid Build Coastguard Worker {
5356*8975f5c5SAndroid Build Coastguard Worker // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
5357*8975f5c5SAndroid Build Coastguard Worker if (n < 0)
5358*8975f5c5SAndroid Build Coastguard Worker {
5359*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
5360*8975f5c5SAndroid Build Coastguard Worker return false;
5361*8975f5c5SAndroid Build Coastguard Worker }
5362*8975f5c5SAndroid Build Coastguard Worker if (n > context->getCaps().maxDrawBuffers)
5363*8975f5c5SAndroid Build Coastguard Worker {
5364*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
5365*8975f5c5SAndroid Build Coastguard Worker return false;
5366*8975f5c5SAndroid Build Coastguard Worker }
5367*8975f5c5SAndroid Build Coastguard Worker
5368*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getState().getDrawFramebuffer());
5369*8975f5c5SAndroid Build Coastguard Worker FramebufferID frameBufferId = context->getState().getDrawFramebuffer()->id();
5370*8975f5c5SAndroid Build Coastguard Worker GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
5371*8975f5c5SAndroid Build Coastguard Worker
5372*8975f5c5SAndroid Build Coastguard Worker // This should come first before the check for the default frame buffer
5373*8975f5c5SAndroid Build Coastguard Worker // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
5374*8975f5c5SAndroid Build Coastguard Worker // rather than INVALID_OPERATION
5375*8975f5c5SAndroid Build Coastguard Worker for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
5376*8975f5c5SAndroid Build Coastguard Worker {
5377*8975f5c5SAndroid Build Coastguard Worker const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
5378*8975f5c5SAndroid Build Coastguard Worker
5379*8975f5c5SAndroid Build Coastguard Worker if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
5380*8975f5c5SAndroid Build Coastguard Worker (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
5381*8975f5c5SAndroid Build Coastguard Worker bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
5382*8975f5c5SAndroid Build Coastguard Worker {
5383*8975f5c5SAndroid Build Coastguard Worker // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
5384*8975f5c5SAndroid Build Coastguard Worker // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
5385*8975f5c5SAndroid Build Coastguard Worker // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
5386*8975f5c5SAndroid Build Coastguard Worker // 3.1 is still a bit ambiguous about the error, but future specs are
5387*8975f5c5SAndroid Build Coastguard Worker // expected to clarify that GL_INVALID_ENUM is the correct error.
5388*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDrawBuffer);
5389*8975f5c5SAndroid Build Coastguard Worker return false;
5390*8975f5c5SAndroid Build Coastguard Worker }
5391*8975f5c5SAndroid Build Coastguard Worker else if (bufs[colorAttachment] >= maxColorAttachment)
5392*8975f5c5SAndroid Build Coastguard Worker {
5393*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
5394*8975f5c5SAndroid Build Coastguard Worker return false;
5395*8975f5c5SAndroid Build Coastguard Worker }
5396*8975f5c5SAndroid Build Coastguard Worker else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
5397*8975f5c5SAndroid Build Coastguard Worker frameBufferId.value != 0)
5398*8975f5c5SAndroid Build Coastguard Worker {
5399*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION-GL is bound to buffer and ith argument
5400*8975f5c5SAndroid Build Coastguard Worker // is not COLOR_ATTACHMENTi or NONE
5401*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawBufferValue);
5402*8975f5c5SAndroid Build Coastguard Worker return false;
5403*8975f5c5SAndroid Build Coastguard Worker }
5404*8975f5c5SAndroid Build Coastguard Worker }
5405*8975f5c5SAndroid Build Coastguard Worker
5406*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION is generated if GL is bound to the default framebuffer
5407*8975f5c5SAndroid Build Coastguard Worker // and n is not 1 or bufs is bound to value other than BACK and NONE
5408*8975f5c5SAndroid Build Coastguard Worker if (frameBufferId.value == 0)
5409*8975f5c5SAndroid Build Coastguard Worker {
5410*8975f5c5SAndroid Build Coastguard Worker if (n != 1)
5411*8975f5c5SAndroid Build Coastguard Worker {
5412*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawBufferCountForDefault);
5413*8975f5c5SAndroid Build Coastguard Worker return false;
5414*8975f5c5SAndroid Build Coastguard Worker }
5415*8975f5c5SAndroid Build Coastguard Worker
5416*8975f5c5SAndroid Build Coastguard Worker if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
5417*8975f5c5SAndroid Build Coastguard Worker {
5418*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferInvalidDrawBuffer);
5419*8975f5c5SAndroid Build Coastguard Worker return false;
5420*8975f5c5SAndroid Build Coastguard Worker }
5421*8975f5c5SAndroid Build Coastguard Worker }
5422*8975f5c5SAndroid Build Coastguard Worker
5423*8975f5c5SAndroid Build Coastguard Worker return true;
5424*8975f5c5SAndroid Build Coastguard Worker }
5425*8975f5c5SAndroid Build Coastguard Worker
ValidateGetBufferPointervBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei * length,void * const * params)5426*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferPointervBase(const Context *context,
5427*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5428*8975f5c5SAndroid Build Coastguard Worker BufferBinding target,
5429*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
5430*8975f5c5SAndroid Build Coastguard Worker GLsizei *length,
5431*8975f5c5SAndroid Build Coastguard Worker void *const *params)
5432*8975f5c5SAndroid Build Coastguard Worker {
5433*8975f5c5SAndroid Build Coastguard Worker if (length)
5434*8975f5c5SAndroid Build Coastguard Worker {
5435*8975f5c5SAndroid Build Coastguard Worker *length = 0;
5436*8975f5c5SAndroid Build Coastguard Worker }
5437*8975f5c5SAndroid Build Coastguard Worker
5438*8975f5c5SAndroid Build Coastguard Worker if (!context->isValidBufferBinding(target))
5439*8975f5c5SAndroid Build Coastguard Worker {
5440*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5441*8975f5c5SAndroid Build Coastguard Worker return false;
5442*8975f5c5SAndroid Build Coastguard Worker }
5443*8975f5c5SAndroid Build Coastguard Worker
5444*8975f5c5SAndroid Build Coastguard Worker switch (pname)
5445*8975f5c5SAndroid Build Coastguard Worker {
5446*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_MAP_POINTER:
5447*8975f5c5SAndroid Build Coastguard Worker break;
5448*8975f5c5SAndroid Build Coastguard Worker
5449*8975f5c5SAndroid Build Coastguard Worker default:
5450*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5451*8975f5c5SAndroid Build Coastguard Worker return false;
5452*8975f5c5SAndroid Build Coastguard Worker }
5453*8975f5c5SAndroid Build Coastguard Worker
5454*8975f5c5SAndroid Build Coastguard Worker // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
5455*8975f5c5SAndroid Build Coastguard Worker // target bound to zero generate an INVALID_OPERATION error."
5456*8975f5c5SAndroid Build Coastguard Worker // GLES 3.1 section 6.6 explicitly specifies this error.
5457*8975f5c5SAndroid Build Coastguard Worker if (context->getState().getTargetBuffer(target) == nullptr)
5458*8975f5c5SAndroid Build Coastguard Worker {
5459*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferPointerNotAvailable);
5460*8975f5c5SAndroid Build Coastguard Worker return false;
5461*8975f5c5SAndroid Build Coastguard Worker }
5462*8975f5c5SAndroid Build Coastguard Worker
5463*8975f5c5SAndroid Build Coastguard Worker if (length)
5464*8975f5c5SAndroid Build Coastguard Worker {
5465*8975f5c5SAndroid Build Coastguard Worker *length = 1;
5466*8975f5c5SAndroid Build Coastguard Worker }
5467*8975f5c5SAndroid Build Coastguard Worker
5468*8975f5c5SAndroid Build Coastguard Worker return true;
5469*8975f5c5SAndroid Build Coastguard Worker }
5470*8975f5c5SAndroid Build Coastguard Worker
ValidateUnmapBufferBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target)5471*8975f5c5SAndroid Build Coastguard Worker bool ValidateUnmapBufferBase(const Context *context,
5472*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5473*8975f5c5SAndroid Build Coastguard Worker BufferBinding target)
5474*8975f5c5SAndroid Build Coastguard Worker {
5475*8975f5c5SAndroid Build Coastguard Worker if (!context->isValidBufferBinding(target))
5476*8975f5c5SAndroid Build Coastguard Worker {
5477*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5478*8975f5c5SAndroid Build Coastguard Worker return false;
5479*8975f5c5SAndroid Build Coastguard Worker }
5480*8975f5c5SAndroid Build Coastguard Worker
5481*8975f5c5SAndroid Build Coastguard Worker Buffer *buffer = context->getState().getTargetBuffer(target);
5482*8975f5c5SAndroid Build Coastguard Worker
5483*8975f5c5SAndroid Build Coastguard Worker if (buffer == nullptr || !buffer->isMapped())
5484*8975f5c5SAndroid Build Coastguard Worker {
5485*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotMapped);
5486*8975f5c5SAndroid Build Coastguard Worker return false;
5487*8975f5c5SAndroid Build Coastguard Worker }
5488*8975f5c5SAndroid Build Coastguard Worker
5489*8975f5c5SAndroid Build Coastguard Worker return true;
5490*8975f5c5SAndroid Build Coastguard Worker }
5491*8975f5c5SAndroid Build Coastguard Worker
ValidateMapBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length,GLbitfield access)5492*8975f5c5SAndroid Build Coastguard Worker bool ValidateMapBufferRangeBase(const Context *context,
5493*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5494*8975f5c5SAndroid Build Coastguard Worker BufferBinding target,
5495*8975f5c5SAndroid Build Coastguard Worker GLintptr offset,
5496*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr length,
5497*8975f5c5SAndroid Build Coastguard Worker GLbitfield access)
5498*8975f5c5SAndroid Build Coastguard Worker {
5499*8975f5c5SAndroid Build Coastguard Worker if (!context->isValidBufferBinding(target))
5500*8975f5c5SAndroid Build Coastguard Worker {
5501*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5502*8975f5c5SAndroid Build Coastguard Worker return false;
5503*8975f5c5SAndroid Build Coastguard Worker }
5504*8975f5c5SAndroid Build Coastguard Worker
5505*8975f5c5SAndroid Build Coastguard Worker if (offset < 0)
5506*8975f5c5SAndroid Build Coastguard Worker {
5507*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
5508*8975f5c5SAndroid Build Coastguard Worker return false;
5509*8975f5c5SAndroid Build Coastguard Worker }
5510*8975f5c5SAndroid Build Coastguard Worker
5511*8975f5c5SAndroid Build Coastguard Worker if (length < 0)
5512*8975f5c5SAndroid Build Coastguard Worker {
5513*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
5514*8975f5c5SAndroid Build Coastguard Worker return false;
5515*8975f5c5SAndroid Build Coastguard Worker }
5516*8975f5c5SAndroid Build Coastguard Worker
5517*8975f5c5SAndroid Build Coastguard Worker Buffer *buffer = context->getState().getTargetBuffer(target);
5518*8975f5c5SAndroid Build Coastguard Worker
5519*8975f5c5SAndroid Build Coastguard Worker if (!buffer)
5520*8975f5c5SAndroid Build Coastguard Worker {
5521*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotMappable);
5522*8975f5c5SAndroid Build Coastguard Worker return false;
5523*8975f5c5SAndroid Build Coastguard Worker }
5524*8975f5c5SAndroid Build Coastguard Worker
5525*8975f5c5SAndroid Build Coastguard Worker // Check for buffer overflow
5526*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<size_t> checkedOffset(offset);
5527*8975f5c5SAndroid Build Coastguard Worker auto checkedSize = checkedOffset + length;
5528*8975f5c5SAndroid Build Coastguard Worker
5529*8975f5c5SAndroid Build Coastguard Worker if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
5530*8975f5c5SAndroid Build Coastguard Worker {
5531*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kMapOutOfRange);
5532*8975f5c5SAndroid Build Coastguard Worker return false;
5533*8975f5c5SAndroid Build Coastguard Worker }
5534*8975f5c5SAndroid Build Coastguard Worker
5535*8975f5c5SAndroid Build Coastguard Worker // Check for invalid bits in the mask
5536*8975f5c5SAndroid Build Coastguard Worker constexpr GLbitfield kAllAccessBits =
5537*8975f5c5SAndroid Build Coastguard Worker GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
5538*8975f5c5SAndroid Build Coastguard Worker GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
5539*8975f5c5SAndroid Build Coastguard Worker
5540*8975f5c5SAndroid Build Coastguard Worker if (buffer->isImmutable())
5541*8975f5c5SAndroid Build Coastguard Worker {
5542*8975f5c5SAndroid Build Coastguard Worker // GL_EXT_buffer_storage's additions to glMapBufferRange
5543*8975f5c5SAndroid Build Coastguard Worker constexpr GLbitfield kBufferStorageAccessBits =
5544*8975f5c5SAndroid Build Coastguard Worker kAllAccessBits | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT;
5545*8975f5c5SAndroid Build Coastguard Worker
5546*8975f5c5SAndroid Build Coastguard Worker if ((access & ~kBufferStorageAccessBits) != 0)
5547*8975f5c5SAndroid Build Coastguard Worker {
5548*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAccessBits);
5549*8975f5c5SAndroid Build Coastguard Worker return false;
5550*8975f5c5SAndroid Build Coastguard Worker }
5551*8975f5c5SAndroid Build Coastguard Worker
5552*8975f5c5SAndroid Build Coastguard Worker // It is invalid if any of bufferStorageMatchedAccessBits bits are included in access,
5553*8975f5c5SAndroid Build Coastguard Worker // but the same bits are not included in the buffer's storage flags
5554*8975f5c5SAndroid Build Coastguard Worker constexpr GLbitfield kBufferStorageMatchedAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
5555*8975f5c5SAndroid Build Coastguard Worker GL_MAP_PERSISTENT_BIT_EXT |
5556*8975f5c5SAndroid Build Coastguard Worker GL_MAP_COHERENT_BIT_EXT;
5557*8975f5c5SAndroid Build Coastguard Worker GLbitfield accessFlags = access & kBufferStorageMatchedAccessBits;
5558*8975f5c5SAndroid Build Coastguard Worker if ((accessFlags & buffer->getStorageExtUsageFlags()) != accessFlags)
5559*8975f5c5SAndroid Build Coastguard Worker {
5560*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBits);
5561*8975f5c5SAndroid Build Coastguard Worker return false;
5562*8975f5c5SAndroid Build Coastguard Worker }
5563*8975f5c5SAndroid Build Coastguard Worker }
5564*8975f5c5SAndroid Build Coastguard Worker else if ((access & ~kAllAccessBits) != 0)
5565*8975f5c5SAndroid Build Coastguard Worker {
5566*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAccessBits);
5567*8975f5c5SAndroid Build Coastguard Worker return false;
5568*8975f5c5SAndroid Build Coastguard Worker }
5569*8975f5c5SAndroid Build Coastguard Worker
5570*8975f5c5SAndroid Build Coastguard Worker if (length == 0)
5571*8975f5c5SAndroid Build Coastguard Worker {
5572*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kLengthZero);
5573*8975f5c5SAndroid Build Coastguard Worker return false;
5574*8975f5c5SAndroid Build Coastguard Worker }
5575*8975f5c5SAndroid Build Coastguard Worker
5576*8975f5c5SAndroid Build Coastguard Worker if (buffer->isMapped())
5577*8975f5c5SAndroid Build Coastguard Worker {
5578*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferAlreadyMapped);
5579*8975f5c5SAndroid Build Coastguard Worker return false;
5580*8975f5c5SAndroid Build Coastguard Worker }
5581*8975f5c5SAndroid Build Coastguard Worker
5582*8975f5c5SAndroid Build Coastguard Worker // Check for invalid bit combinations
5583*8975f5c5SAndroid Build Coastguard Worker if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
5584*8975f5c5SAndroid Build Coastguard Worker {
5585*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite);
5586*8975f5c5SAndroid Build Coastguard Worker return false;
5587*8975f5c5SAndroid Build Coastguard Worker }
5588*8975f5c5SAndroid Build Coastguard Worker
5589*8975f5c5SAndroid Build Coastguard Worker GLbitfield writeOnlyBits =
5590*8975f5c5SAndroid Build Coastguard Worker GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
5591*8975f5c5SAndroid Build Coastguard Worker
5592*8975f5c5SAndroid Build Coastguard Worker if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
5593*8975f5c5SAndroid Build Coastguard Worker {
5594*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBitsRead);
5595*8975f5c5SAndroid Build Coastguard Worker return false;
5596*8975f5c5SAndroid Build Coastguard Worker }
5597*8975f5c5SAndroid Build Coastguard Worker
5598*8975f5c5SAndroid Build Coastguard Worker if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
5599*8975f5c5SAndroid Build Coastguard Worker {
5600*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBitsFlush);
5601*8975f5c5SAndroid Build Coastguard Worker return false;
5602*8975f5c5SAndroid Build Coastguard Worker }
5603*8975f5c5SAndroid Build Coastguard Worker
5604*8975f5c5SAndroid Build Coastguard Worker return ValidateMapBufferBase(context, entryPoint, target);
5605*8975f5c5SAndroid Build Coastguard Worker }
5606*8975f5c5SAndroid Build Coastguard Worker
ValidateFlushMappedBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length)5607*8975f5c5SAndroid Build Coastguard Worker bool ValidateFlushMappedBufferRangeBase(const Context *context,
5608*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5609*8975f5c5SAndroid Build Coastguard Worker BufferBinding target,
5610*8975f5c5SAndroid Build Coastguard Worker GLintptr offset,
5611*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr length)
5612*8975f5c5SAndroid Build Coastguard Worker {
5613*8975f5c5SAndroid Build Coastguard Worker if (offset < 0)
5614*8975f5c5SAndroid Build Coastguard Worker {
5615*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
5616*8975f5c5SAndroid Build Coastguard Worker return false;
5617*8975f5c5SAndroid Build Coastguard Worker }
5618*8975f5c5SAndroid Build Coastguard Worker
5619*8975f5c5SAndroid Build Coastguard Worker if (length < 0)
5620*8975f5c5SAndroid Build Coastguard Worker {
5621*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
5622*8975f5c5SAndroid Build Coastguard Worker return false;
5623*8975f5c5SAndroid Build Coastguard Worker }
5624*8975f5c5SAndroid Build Coastguard Worker
5625*8975f5c5SAndroid Build Coastguard Worker if (!context->isValidBufferBinding(target))
5626*8975f5c5SAndroid Build Coastguard Worker {
5627*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5628*8975f5c5SAndroid Build Coastguard Worker return false;
5629*8975f5c5SAndroid Build Coastguard Worker }
5630*8975f5c5SAndroid Build Coastguard Worker
5631*8975f5c5SAndroid Build Coastguard Worker Buffer *buffer = context->getState().getTargetBuffer(target);
5632*8975f5c5SAndroid Build Coastguard Worker
5633*8975f5c5SAndroid Build Coastguard Worker if (buffer == nullptr)
5634*8975f5c5SAndroid Build Coastguard Worker {
5635*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFlushZero);
5636*8975f5c5SAndroid Build Coastguard Worker return false;
5637*8975f5c5SAndroid Build Coastguard Worker }
5638*8975f5c5SAndroid Build Coastguard Worker
5639*8975f5c5SAndroid Build Coastguard Worker if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
5640*8975f5c5SAndroid Build Coastguard Worker {
5641*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFlushTarget);
5642*8975f5c5SAndroid Build Coastguard Worker return false;
5643*8975f5c5SAndroid Build Coastguard Worker }
5644*8975f5c5SAndroid Build Coastguard Worker
5645*8975f5c5SAndroid Build Coastguard Worker // Check for buffer overflow
5646*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<size_t> checkedOffset(offset);
5647*8975f5c5SAndroid Build Coastguard Worker auto checkedSize = checkedOffset + length;
5648*8975f5c5SAndroid Build Coastguard Worker
5649*8975f5c5SAndroid Build Coastguard Worker if (!checkedSize.IsValid() ||
5650*8975f5c5SAndroid Build Coastguard Worker checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
5651*8975f5c5SAndroid Build Coastguard Worker {
5652*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFlushOutOfRange);
5653*8975f5c5SAndroid Build Coastguard Worker return false;
5654*8975f5c5SAndroid Build Coastguard Worker }
5655*8975f5c5SAndroid Build Coastguard Worker
5656*8975f5c5SAndroid Build Coastguard Worker return true;
5657*8975f5c5SAndroid Build Coastguard Worker }
5658*8975f5c5SAndroid Build Coastguard Worker
ValidateGenOrDelete(const Context * context,angle::EntryPoint entryPoint,GLint n)5659*8975f5c5SAndroid Build Coastguard Worker bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n)
5660*8975f5c5SAndroid Build Coastguard Worker {
5661*8975f5c5SAndroid Build Coastguard Worker if (n < 0)
5662*8975f5c5SAndroid Build Coastguard Worker {
5663*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
5664*8975f5c5SAndroid Build Coastguard Worker return false;
5665*8975f5c5SAndroid Build Coastguard Worker }
5666*8975f5c5SAndroid Build Coastguard Worker return true;
5667*8975f5c5SAndroid Build Coastguard Worker }
5668*8975f5c5SAndroid Build Coastguard Worker
ValidateRobustEntryPoint(const Context * context,angle::EntryPoint entryPoint,GLsizei bufSize)5669*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustEntryPoint(const Context *context, angle::EntryPoint entryPoint, GLsizei bufSize)
5670*8975f5c5SAndroid Build Coastguard Worker {
5671*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().robustClientMemoryANGLE)
5672*8975f5c5SAndroid Build Coastguard Worker {
5673*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5674*8975f5c5SAndroid Build Coastguard Worker return false;
5675*8975f5c5SAndroid Build Coastguard Worker }
5676*8975f5c5SAndroid Build Coastguard Worker
5677*8975f5c5SAndroid Build Coastguard Worker if (bufSize < 0)
5678*8975f5c5SAndroid Build Coastguard Worker {
5679*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
5680*8975f5c5SAndroid Build Coastguard Worker return false;
5681*8975f5c5SAndroid Build Coastguard Worker }
5682*8975f5c5SAndroid Build Coastguard Worker
5683*8975f5c5SAndroid Build Coastguard Worker return true;
5684*8975f5c5SAndroid Build Coastguard Worker }
5685*8975f5c5SAndroid Build Coastguard Worker
ValidateRobustBufferSize(const Context * context,angle::EntryPoint entryPoint,GLsizei bufSize,GLsizei numParams)5686*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustBufferSize(const Context *context,
5687*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5688*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
5689*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams)
5690*8975f5c5SAndroid Build Coastguard Worker {
5691*8975f5c5SAndroid Build Coastguard Worker if (bufSize < numParams)
5692*8975f5c5SAndroid Build Coastguard Worker {
5693*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientParams);
5694*8975f5c5SAndroid Build Coastguard Worker return false;
5695*8975f5c5SAndroid Build Coastguard Worker }
5696*8975f5c5SAndroid Build Coastguard Worker
5697*8975f5c5SAndroid Build Coastguard Worker return true;
5698*8975f5c5SAndroid Build Coastguard Worker }
5699*8975f5c5SAndroid Build Coastguard Worker
ValidateGetFramebufferAttachmentParameterivBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum pname,GLsizei * numParams)5700*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
5701*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5702*8975f5c5SAndroid Build Coastguard Worker GLenum target,
5703*8975f5c5SAndroid Build Coastguard Worker GLenum attachment,
5704*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
5705*8975f5c5SAndroid Build Coastguard Worker GLsizei *numParams)
5706*8975f5c5SAndroid Build Coastguard Worker {
5707*8975f5c5SAndroid Build Coastguard Worker if (!ValidFramebufferTarget(context, target))
5708*8975f5c5SAndroid Build Coastguard Worker {
5709*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
5710*8975f5c5SAndroid Build Coastguard Worker return false;
5711*8975f5c5SAndroid Build Coastguard Worker }
5712*8975f5c5SAndroid Build Coastguard Worker
5713*8975f5c5SAndroid Build Coastguard Worker int clientVersion = context->getClientMajorVersion();
5714*8975f5c5SAndroid Build Coastguard Worker
5715*8975f5c5SAndroid Build Coastguard Worker switch (pname)
5716*8975f5c5SAndroid Build Coastguard Worker {
5717*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
5718*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
5719*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
5720*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
5721*8975f5c5SAndroid Build Coastguard Worker break;
5722*8975f5c5SAndroid Build Coastguard Worker
5723*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
5724*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
5725*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3 ||
5726*8975f5c5SAndroid Build Coastguard Worker !(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR))
5727*8975f5c5SAndroid Build Coastguard Worker {
5728*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5729*8975f5c5SAndroid Build Coastguard Worker return false;
5730*8975f5c5SAndroid Build Coastguard Worker }
5731*8975f5c5SAndroid Build Coastguard Worker break;
5732*8975f5c5SAndroid Build Coastguard Worker
5733*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
5734*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().multisampledRenderToTextureEXT)
5735*8975f5c5SAndroid Build Coastguard Worker {
5736*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5737*8975f5c5SAndroid Build Coastguard Worker return false;
5738*8975f5c5SAndroid Build Coastguard Worker }
5739*8975f5c5SAndroid Build Coastguard Worker break;
5740*8975f5c5SAndroid Build Coastguard Worker
5741*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
5742*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3 && !context->getExtensions().sRGBEXT)
5743*8975f5c5SAndroid Build Coastguard Worker {
5744*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5745*8975f5c5SAndroid Build Coastguard Worker return false;
5746*8975f5c5SAndroid Build Coastguard Worker }
5747*8975f5c5SAndroid Build Coastguard Worker break;
5748*8975f5c5SAndroid Build Coastguard Worker
5749*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
5750*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3 && !context->getExtensions().colorBufferHalfFloatEXT &&
5751*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().colorBufferFloatRgbCHROMIUM &&
5752*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().colorBufferFloatRgbaCHROMIUM)
5753*8975f5c5SAndroid Build Coastguard Worker {
5754*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5755*8975f5c5SAndroid Build Coastguard Worker return false;
5756*8975f5c5SAndroid Build Coastguard Worker }
5757*8975f5c5SAndroid Build Coastguard Worker break;
5758*8975f5c5SAndroid Build Coastguard Worker
5759*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
5760*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
5761*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
5762*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
5763*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
5764*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
5765*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
5766*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3)
5767*8975f5c5SAndroid Build Coastguard Worker {
5768*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES3Required);
5769*8975f5c5SAndroid Build Coastguard Worker return false;
5770*8975f5c5SAndroid Build Coastguard Worker }
5771*8975f5c5SAndroid Build Coastguard Worker break;
5772*8975f5c5SAndroid Build Coastguard Worker
5773*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
5774*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().geometryShaderAny() &&
5775*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
5776*8975f5c5SAndroid Build Coastguard Worker {
5777*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
5778*8975f5c5SAndroid Build Coastguard Worker return false;
5779*8975f5c5SAndroid Build Coastguard Worker }
5780*8975f5c5SAndroid Build Coastguard Worker break;
5781*8975f5c5SAndroid Build Coastguard Worker
5782*8975f5c5SAndroid Build Coastguard Worker default:
5783*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
5784*8975f5c5SAndroid Build Coastguard Worker return false;
5785*8975f5c5SAndroid Build Coastguard Worker }
5786*8975f5c5SAndroid Build Coastguard Worker
5787*8975f5c5SAndroid Build Coastguard Worker // Determine if the attachment is a valid enum
5788*8975f5c5SAndroid Build Coastguard Worker switch (attachment)
5789*8975f5c5SAndroid Build Coastguard Worker {
5790*8975f5c5SAndroid Build Coastguard Worker case GL_BACK:
5791*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH:
5792*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL:
5793*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3)
5794*8975f5c5SAndroid Build Coastguard Worker {
5795*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5796*8975f5c5SAndroid Build Coastguard Worker return false;
5797*8975f5c5SAndroid Build Coastguard Worker }
5798*8975f5c5SAndroid Build Coastguard Worker break;
5799*8975f5c5SAndroid Build Coastguard Worker
5800*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
5801*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3 && !context->isWebGL1())
5802*8975f5c5SAndroid Build Coastguard Worker {
5803*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5804*8975f5c5SAndroid Build Coastguard Worker return false;
5805*8975f5c5SAndroid Build Coastguard Worker }
5806*8975f5c5SAndroid Build Coastguard Worker break;
5807*8975f5c5SAndroid Build Coastguard Worker
5808*8975f5c5SAndroid Build Coastguard Worker case GL_COLOR_ATTACHMENT0:
5809*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
5810*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
5811*8975f5c5SAndroid Build Coastguard Worker break;
5812*8975f5c5SAndroid Build Coastguard Worker
5813*8975f5c5SAndroid Build Coastguard Worker default:
5814*8975f5c5SAndroid Build Coastguard Worker if ((clientVersion < 3 && !context->getExtensions().drawBuffersEXT) ||
5815*8975f5c5SAndroid Build Coastguard Worker attachment < GL_COLOR_ATTACHMENT0_EXT ||
5816*8975f5c5SAndroid Build Coastguard Worker (attachment - GL_COLOR_ATTACHMENT0_EXT) >=
5817*8975f5c5SAndroid Build Coastguard Worker static_cast<GLuint>(context->getCaps().maxColorAttachments))
5818*8975f5c5SAndroid Build Coastguard Worker {
5819*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5820*8975f5c5SAndroid Build Coastguard Worker return false;
5821*8975f5c5SAndroid Build Coastguard Worker }
5822*8975f5c5SAndroid Build Coastguard Worker break;
5823*8975f5c5SAndroid Build Coastguard Worker }
5824*8975f5c5SAndroid Build Coastguard Worker
5825*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
5826*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
5827*8975f5c5SAndroid Build Coastguard Worker
5828*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->isDefault())
5829*8975f5c5SAndroid Build Coastguard Worker {
5830*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3)
5831*8975f5c5SAndroid Build Coastguard Worker {
5832*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
5833*8975f5c5SAndroid Build Coastguard Worker return false;
5834*8975f5c5SAndroid Build Coastguard Worker }
5835*8975f5c5SAndroid Build Coastguard Worker
5836*8975f5c5SAndroid Build Coastguard Worker switch (attachment)
5837*8975f5c5SAndroid Build Coastguard Worker {
5838*8975f5c5SAndroid Build Coastguard Worker case GL_BACK:
5839*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH:
5840*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL:
5841*8975f5c5SAndroid Build Coastguard Worker break;
5842*8975f5c5SAndroid Build Coastguard Worker
5843*8975f5c5SAndroid Build Coastguard Worker default:
5844*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5845*8975f5c5SAndroid Build Coastguard Worker return false;
5846*8975f5c5SAndroid Build Coastguard Worker }
5847*8975f5c5SAndroid Build Coastguard Worker }
5848*8975f5c5SAndroid Build Coastguard Worker else
5849*8975f5c5SAndroid Build Coastguard Worker {
5850*8975f5c5SAndroid Build Coastguard Worker if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
5851*8975f5c5SAndroid Build Coastguard Worker {
5852*8975f5c5SAndroid Build Coastguard Worker // Valid attachment query
5853*8975f5c5SAndroid Build Coastguard Worker }
5854*8975f5c5SAndroid Build Coastguard Worker else
5855*8975f5c5SAndroid Build Coastguard Worker {
5856*8975f5c5SAndroid Build Coastguard Worker switch (attachment)
5857*8975f5c5SAndroid Build Coastguard Worker {
5858*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_ATTACHMENT:
5859*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_ATTACHMENT:
5860*8975f5c5SAndroid Build Coastguard Worker break;
5861*8975f5c5SAndroid Build Coastguard Worker
5862*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_ATTACHMENT:
5863*8975f5c5SAndroid Build Coastguard Worker if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
5864*8975f5c5SAndroid Build Coastguard Worker {
5865*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5866*8975f5c5SAndroid Build Coastguard Worker return false;
5867*8975f5c5SAndroid Build Coastguard Worker }
5868*8975f5c5SAndroid Build Coastguard Worker break;
5869*8975f5c5SAndroid Build Coastguard Worker
5870*8975f5c5SAndroid Build Coastguard Worker default:
5871*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5872*8975f5c5SAndroid Build Coastguard Worker return false;
5873*8975f5c5SAndroid Build Coastguard Worker }
5874*8975f5c5SAndroid Build Coastguard Worker }
5875*8975f5c5SAndroid Build Coastguard Worker }
5876*8975f5c5SAndroid Build Coastguard Worker
5877*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
5878*8975f5c5SAndroid Build Coastguard Worker if (attachmentObject)
5879*8975f5c5SAndroid Build Coastguard Worker {
5880*8975f5c5SAndroid Build Coastguard Worker ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
5881*8975f5c5SAndroid Build Coastguard Worker attachmentObject->type() == GL_TEXTURE ||
5882*8975f5c5SAndroid Build Coastguard Worker attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
5883*8975f5c5SAndroid Build Coastguard Worker
5884*8975f5c5SAndroid Build Coastguard Worker switch (pname)
5885*8975f5c5SAndroid Build Coastguard Worker {
5886*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
5887*8975f5c5SAndroid Build Coastguard Worker if (attachmentObject->type() != GL_RENDERBUFFER &&
5888*8975f5c5SAndroid Build Coastguard Worker attachmentObject->type() != GL_TEXTURE)
5889*8975f5c5SAndroid Build Coastguard Worker {
5890*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5891*8975f5c5SAndroid Build Coastguard Worker return false;
5892*8975f5c5SAndroid Build Coastguard Worker }
5893*8975f5c5SAndroid Build Coastguard Worker break;
5894*8975f5c5SAndroid Build Coastguard Worker
5895*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
5896*8975f5c5SAndroid Build Coastguard Worker if (attachmentObject->type() != GL_TEXTURE)
5897*8975f5c5SAndroid Build Coastguard Worker {
5898*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5899*8975f5c5SAndroid Build Coastguard Worker return false;
5900*8975f5c5SAndroid Build Coastguard Worker }
5901*8975f5c5SAndroid Build Coastguard Worker break;
5902*8975f5c5SAndroid Build Coastguard Worker
5903*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
5904*8975f5c5SAndroid Build Coastguard Worker if (attachmentObject->type() != GL_TEXTURE)
5905*8975f5c5SAndroid Build Coastguard Worker {
5906*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5907*8975f5c5SAndroid Build Coastguard Worker return false;
5908*8975f5c5SAndroid Build Coastguard Worker }
5909*8975f5c5SAndroid Build Coastguard Worker break;
5910*8975f5c5SAndroid Build Coastguard Worker
5911*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
5912*8975f5c5SAndroid Build Coastguard Worker if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
5913*8975f5c5SAndroid Build Coastguard Worker {
5914*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5915*8975f5c5SAndroid Build Coastguard Worker return false;
5916*8975f5c5SAndroid Build Coastguard Worker }
5917*8975f5c5SAndroid Build Coastguard Worker break;
5918*8975f5c5SAndroid Build Coastguard Worker
5919*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
5920*8975f5c5SAndroid Build Coastguard Worker if (attachmentObject->type() != GL_TEXTURE)
5921*8975f5c5SAndroid Build Coastguard Worker {
5922*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5923*8975f5c5SAndroid Build Coastguard Worker return false;
5924*8975f5c5SAndroid Build Coastguard Worker }
5925*8975f5c5SAndroid Build Coastguard Worker break;
5926*8975f5c5SAndroid Build Coastguard Worker
5927*8975f5c5SAndroid Build Coastguard Worker default:
5928*8975f5c5SAndroid Build Coastguard Worker break;
5929*8975f5c5SAndroid Build Coastguard Worker }
5930*8975f5c5SAndroid Build Coastguard Worker }
5931*8975f5c5SAndroid Build Coastguard Worker else
5932*8975f5c5SAndroid Build Coastguard Worker {
5933*8975f5c5SAndroid Build Coastguard Worker // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
5934*8975f5c5SAndroid Build Coastguard Worker // is NONE, then querying any other pname will generate INVALID_ENUM.
5935*8975f5c5SAndroid Build Coastguard Worker
5936*8975f5c5SAndroid Build Coastguard Worker // ES 3.0.2 spec pg 235 states that if the attachment type is none,
5937*8975f5c5SAndroid Build Coastguard Worker // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
5938*8975f5c5SAndroid Build Coastguard Worker // INVALID_OPERATION for all other pnames
5939*8975f5c5SAndroid Build Coastguard Worker
5940*8975f5c5SAndroid Build Coastguard Worker switch (pname)
5941*8975f5c5SAndroid Build Coastguard Worker {
5942*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
5943*8975f5c5SAndroid Build Coastguard Worker break;
5944*8975f5c5SAndroid Build Coastguard Worker
5945*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
5946*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3)
5947*8975f5c5SAndroid Build Coastguard Worker {
5948*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferAttachmentParameter);
5949*8975f5c5SAndroid Build Coastguard Worker return false;
5950*8975f5c5SAndroid Build Coastguard Worker }
5951*8975f5c5SAndroid Build Coastguard Worker break;
5952*8975f5c5SAndroid Build Coastguard Worker
5953*8975f5c5SAndroid Build Coastguard Worker default:
5954*8975f5c5SAndroid Build Coastguard Worker if (clientVersion < 3)
5955*8975f5c5SAndroid Build Coastguard Worker {
5956*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferAttachmentParameter);
5957*8975f5c5SAndroid Build Coastguard Worker return false;
5958*8975f5c5SAndroid Build Coastguard Worker }
5959*8975f5c5SAndroid Build Coastguard Worker else
5960*8975f5c5SAndroid Build Coastguard Worker {
5961*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5962*8975f5c5SAndroid Build Coastguard Worker kInvalidFramebufferAttachmentParameter);
5963*8975f5c5SAndroid Build Coastguard Worker return false;
5964*8975f5c5SAndroid Build Coastguard Worker }
5965*8975f5c5SAndroid Build Coastguard Worker }
5966*8975f5c5SAndroid Build Coastguard Worker }
5967*8975f5c5SAndroid Build Coastguard Worker
5968*8975f5c5SAndroid Build Coastguard Worker if (numParams)
5969*8975f5c5SAndroid Build Coastguard Worker {
5970*8975f5c5SAndroid Build Coastguard Worker *numParams = 1;
5971*8975f5c5SAndroid Build Coastguard Worker }
5972*8975f5c5SAndroid Build Coastguard Worker
5973*8975f5c5SAndroid Build Coastguard Worker return true;
5974*8975f5c5SAndroid Build Coastguard Worker }
5975*8975f5c5SAndroid Build Coastguard Worker
ValidateGetFramebufferParameterivBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)5976*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFramebufferParameterivBase(const Context *context,
5977*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
5978*8975f5c5SAndroid Build Coastguard Worker GLenum target,
5979*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
5980*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
5981*8975f5c5SAndroid Build Coastguard Worker {
5982*8975f5c5SAndroid Build Coastguard Worker if (!ValidFramebufferTarget(context, target))
5983*8975f5c5SAndroid Build Coastguard Worker {
5984*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
5985*8975f5c5SAndroid Build Coastguard Worker return false;
5986*8975f5c5SAndroid Build Coastguard Worker }
5987*8975f5c5SAndroid Build Coastguard Worker
5988*8975f5c5SAndroid Build Coastguard Worker switch (pname)
5989*8975f5c5SAndroid Build Coastguard Worker {
5990*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_WIDTH:
5991*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
5992*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
5993*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
5994*8975f5c5SAndroid Build Coastguard Worker break;
5995*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
5996*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().geometryShaderAny() &&
5997*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
5998*8975f5c5SAndroid Build Coastguard Worker {
5999*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
6000*8975f5c5SAndroid Build Coastguard Worker return false;
6001*8975f5c5SAndroid Build Coastguard Worker }
6002*8975f5c5SAndroid Build Coastguard Worker break;
6003*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_FLIP_Y_MESA:
6004*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().framebufferFlipYMESA)
6005*8975f5c5SAndroid Build Coastguard Worker {
6006*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
6007*8975f5c5SAndroid Build Coastguard Worker return false;
6008*8975f5c5SAndroid Build Coastguard Worker }
6009*8975f5c5SAndroid Build Coastguard Worker break;
6010*8975f5c5SAndroid Build Coastguard Worker default:
6011*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
6012*8975f5c5SAndroid Build Coastguard Worker return false;
6013*8975f5c5SAndroid Build Coastguard Worker }
6014*8975f5c5SAndroid Build Coastguard Worker
6015*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
6016*8975f5c5SAndroid Build Coastguard Worker ASSERT(framebuffer);
6017*8975f5c5SAndroid Build Coastguard Worker
6018*8975f5c5SAndroid Build Coastguard Worker if (framebuffer->isDefault())
6019*8975f5c5SAndroid Build Coastguard Worker {
6020*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebuffer);
6021*8975f5c5SAndroid Build Coastguard Worker return false;
6022*8975f5c5SAndroid Build Coastguard Worker }
6023*8975f5c5SAndroid Build Coastguard Worker return true;
6024*8975f5c5SAndroid Build Coastguard Worker }
6025*8975f5c5SAndroid Build Coastguard Worker
ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6026*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context *context,
6027*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6028*8975f5c5SAndroid Build Coastguard Worker GLenum target,
6029*8975f5c5SAndroid Build Coastguard Worker GLenum attachment,
6030*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6031*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6032*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6033*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6034*8975f5c5SAndroid Build Coastguard Worker {
6035*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6036*8975f5c5SAndroid Build Coastguard Worker {
6037*8975f5c5SAndroid Build Coastguard Worker return false;
6038*8975f5c5SAndroid Build Coastguard Worker }
6039*8975f5c5SAndroid Build Coastguard Worker
6040*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6041*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
6042*8975f5c5SAndroid Build Coastguard Worker pname, &numParams))
6043*8975f5c5SAndroid Build Coastguard Worker {
6044*8975f5c5SAndroid Build Coastguard Worker return false;
6045*8975f5c5SAndroid Build Coastguard Worker }
6046*8975f5c5SAndroid Build Coastguard Worker
6047*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6048*8975f5c5SAndroid Build Coastguard Worker {
6049*8975f5c5SAndroid Build Coastguard Worker return false;
6050*8975f5c5SAndroid Build Coastguard Worker }
6051*8975f5c5SAndroid Build Coastguard Worker
6052*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6053*8975f5c5SAndroid Build Coastguard Worker
6054*8975f5c5SAndroid Build Coastguard Worker return true;
6055*8975f5c5SAndroid Build Coastguard Worker }
6056*8975f5c5SAndroid Build Coastguard Worker
ValidateGetBufferParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6057*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferParameterivRobustANGLE(const Context *context,
6058*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6059*8975f5c5SAndroid Build Coastguard Worker BufferBinding target,
6060*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6061*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6062*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6063*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6064*8975f5c5SAndroid Build Coastguard Worker {
6065*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6066*8975f5c5SAndroid Build Coastguard Worker {
6067*8975f5c5SAndroid Build Coastguard Worker return false;
6068*8975f5c5SAndroid Build Coastguard Worker }
6069*8975f5c5SAndroid Build Coastguard Worker
6070*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6071*8975f5c5SAndroid Build Coastguard Worker
6072*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams))
6073*8975f5c5SAndroid Build Coastguard Worker {
6074*8975f5c5SAndroid Build Coastguard Worker return false;
6075*8975f5c5SAndroid Build Coastguard Worker }
6076*8975f5c5SAndroid Build Coastguard Worker
6077*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6078*8975f5c5SAndroid Build Coastguard Worker {
6079*8975f5c5SAndroid Build Coastguard Worker return false;
6080*8975f5c5SAndroid Build Coastguard Worker }
6081*8975f5c5SAndroid Build Coastguard Worker
6082*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6083*8975f5c5SAndroid Build Coastguard Worker return true;
6084*8975f5c5SAndroid Build Coastguard Worker }
6085*8975f5c5SAndroid Build Coastguard Worker
ValidateGetBufferParameteri64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint64 * params)6086*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferParameteri64vRobustANGLE(const Context *context,
6087*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6088*8975f5c5SAndroid Build Coastguard Worker BufferBinding target,
6089*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6090*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6091*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6092*8975f5c5SAndroid Build Coastguard Worker const GLint64 *params)
6093*8975f5c5SAndroid Build Coastguard Worker {
6094*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6095*8975f5c5SAndroid Build Coastguard Worker
6096*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6097*8975f5c5SAndroid Build Coastguard Worker {
6098*8975f5c5SAndroid Build Coastguard Worker return false;
6099*8975f5c5SAndroid Build Coastguard Worker }
6100*8975f5c5SAndroid Build Coastguard Worker
6101*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams))
6102*8975f5c5SAndroid Build Coastguard Worker {
6103*8975f5c5SAndroid Build Coastguard Worker return false;
6104*8975f5c5SAndroid Build Coastguard Worker }
6105*8975f5c5SAndroid Build Coastguard Worker
6106*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6107*8975f5c5SAndroid Build Coastguard Worker {
6108*8975f5c5SAndroid Build Coastguard Worker return false;
6109*8975f5c5SAndroid Build Coastguard Worker }
6110*8975f5c5SAndroid Build Coastguard Worker
6111*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6112*8975f5c5SAndroid Build Coastguard Worker
6113*8975f5c5SAndroid Build Coastguard Worker return true;
6114*8975f5c5SAndroid Build Coastguard Worker }
6115*8975f5c5SAndroid Build Coastguard Worker
ValidateGetProgramivBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,GLsizei * numParams)6116*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProgramivBase(const Context *context,
6117*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6118*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
6119*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6120*8975f5c5SAndroid Build Coastguard Worker GLsizei *numParams)
6121*8975f5c5SAndroid Build Coastguard Worker {
6122*8975f5c5SAndroid Build Coastguard Worker // Currently, all GetProgramiv queries return 1 parameter
6123*8975f5c5SAndroid Build Coastguard Worker if (numParams)
6124*8975f5c5SAndroid Build Coastguard Worker {
6125*8975f5c5SAndroid Build Coastguard Worker *numParams = 1;
6126*8975f5c5SAndroid Build Coastguard Worker }
6127*8975f5c5SAndroid Build Coastguard Worker
6128*8975f5c5SAndroid Build Coastguard Worker if (context->isContextLost())
6129*8975f5c5SAndroid Build Coastguard Worker {
6130*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
6131*8975f5c5SAndroid Build Coastguard Worker
6132*8975f5c5SAndroid Build Coastguard Worker if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR)
6133*8975f5c5SAndroid Build Coastguard Worker {
6134*8975f5c5SAndroid Build Coastguard Worker // Generate an error but still return true, the context still needs to return a
6135*8975f5c5SAndroid Build Coastguard Worker // value in this case.
6136*8975f5c5SAndroid Build Coastguard Worker return true;
6137*8975f5c5SAndroid Build Coastguard Worker }
6138*8975f5c5SAndroid Build Coastguard Worker else
6139*8975f5c5SAndroid Build Coastguard Worker {
6140*8975f5c5SAndroid Build Coastguard Worker return false;
6141*8975f5c5SAndroid Build Coastguard Worker }
6142*8975f5c5SAndroid Build Coastguard Worker }
6143*8975f5c5SAndroid Build Coastguard Worker
6144*8975f5c5SAndroid Build Coastguard Worker // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
6145*8975f5c5SAndroid Build Coastguard Worker Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
6146*8975f5c5SAndroid Build Coastguard Worker ? GetValidProgramNoResolve(context, entryPoint, program)
6147*8975f5c5SAndroid Build Coastguard Worker : GetValidProgram(context, entryPoint, program);
6148*8975f5c5SAndroid Build Coastguard Worker if (!programObject)
6149*8975f5c5SAndroid Build Coastguard Worker {
6150*8975f5c5SAndroid Build Coastguard Worker return false;
6151*8975f5c5SAndroid Build Coastguard Worker }
6152*8975f5c5SAndroid Build Coastguard Worker
6153*8975f5c5SAndroid Build Coastguard Worker switch (pname)
6154*8975f5c5SAndroid Build Coastguard Worker {
6155*8975f5c5SAndroid Build Coastguard Worker case GL_DELETE_STATUS:
6156*8975f5c5SAndroid Build Coastguard Worker case GL_LINK_STATUS:
6157*8975f5c5SAndroid Build Coastguard Worker case GL_VALIDATE_STATUS:
6158*8975f5c5SAndroid Build Coastguard Worker case GL_INFO_LOG_LENGTH:
6159*8975f5c5SAndroid Build Coastguard Worker case GL_ATTACHED_SHADERS:
6160*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_ATTRIBUTES:
6161*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
6162*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_UNIFORMS:
6163*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_UNIFORM_MAX_LENGTH:
6164*8975f5c5SAndroid Build Coastguard Worker break;
6165*8975f5c5SAndroid Build Coastguard Worker
6166*8975f5c5SAndroid Build Coastguard Worker case GL_PROGRAM_BINARY_READY_ANGLE:
6167*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().programBinaryReadinessQueryANGLE)
6168*8975f5c5SAndroid Build Coastguard Worker {
6169*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6170*8975f5c5SAndroid Build Coastguard Worker return false;
6171*8975f5c5SAndroid Build Coastguard Worker }
6172*8975f5c5SAndroid Build Coastguard Worker break;
6173*8975f5c5SAndroid Build Coastguard Worker
6174*8975f5c5SAndroid Build Coastguard Worker case GL_PROGRAM_BINARY_LENGTH:
6175*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 &&
6176*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().getProgramBinaryOES)
6177*8975f5c5SAndroid Build Coastguard Worker {
6178*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6179*8975f5c5SAndroid Build Coastguard Worker return false;
6180*8975f5c5SAndroid Build Coastguard Worker }
6181*8975f5c5SAndroid Build Coastguard Worker break;
6182*8975f5c5SAndroid Build Coastguard Worker
6183*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_UNIFORM_BLOCKS:
6184*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
6185*8975f5c5SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
6186*8975f5c5SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_VARYINGS:
6187*8975f5c5SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
6188*8975f5c5SAndroid Build Coastguard Worker case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
6189*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
6190*8975f5c5SAndroid Build Coastguard Worker {
6191*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES30);
6192*8975f5c5SAndroid Build Coastguard Worker return false;
6193*8975f5c5SAndroid Build Coastguard Worker }
6194*8975f5c5SAndroid Build Coastguard Worker break;
6195*8975f5c5SAndroid Build Coastguard Worker
6196*8975f5c5SAndroid Build Coastguard Worker case GL_PROGRAM_SEPARABLE:
6197*8975f5c5SAndroid Build Coastguard Worker case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
6198*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 1))
6199*8975f5c5SAndroid Build Coastguard Worker {
6200*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
6201*8975f5c5SAndroid Build Coastguard Worker return false;
6202*8975f5c5SAndroid Build Coastguard Worker }
6203*8975f5c5SAndroid Build Coastguard Worker break;
6204*8975f5c5SAndroid Build Coastguard Worker
6205*8975f5c5SAndroid Build Coastguard Worker case GL_COMPUTE_WORK_GROUP_SIZE:
6206*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 1))
6207*8975f5c5SAndroid Build Coastguard Worker {
6208*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
6209*8975f5c5SAndroid Build Coastguard Worker return false;
6210*8975f5c5SAndroid Build Coastguard Worker }
6211*8975f5c5SAndroid Build Coastguard Worker
6212*8975f5c5SAndroid Build Coastguard Worker // [OpenGL ES 3.1] Chapter 7.12 Page 122
6213*8975f5c5SAndroid Build Coastguard Worker // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
6214*8975f5c5SAndroid Build Coastguard Worker // program which has not been linked successfully, or which does not contain objects to
6215*8975f5c5SAndroid Build Coastguard Worker // form a compute shader.
6216*8975f5c5SAndroid Build Coastguard Worker if (!programObject->isLinked())
6217*8975f5c5SAndroid Build Coastguard Worker {
6218*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6219*8975f5c5SAndroid Build Coastguard Worker return false;
6220*8975f5c5SAndroid Build Coastguard Worker }
6221*8975f5c5SAndroid Build Coastguard Worker if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Compute))
6222*8975f5c5SAndroid Build Coastguard Worker {
6223*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
6224*8975f5c5SAndroid Build Coastguard Worker return false;
6225*8975f5c5SAndroid Build Coastguard Worker }
6226*8975f5c5SAndroid Build Coastguard Worker break;
6227*8975f5c5SAndroid Build Coastguard Worker
6228*8975f5c5SAndroid Build Coastguard Worker case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
6229*8975f5c5SAndroid Build Coastguard Worker case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
6230*8975f5c5SAndroid Build Coastguard Worker case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
6231*8975f5c5SAndroid Build Coastguard Worker case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
6232*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().geometryShaderAny() &&
6233*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
6234*8975f5c5SAndroid Build Coastguard Worker {
6235*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
6236*8975f5c5SAndroid Build Coastguard Worker return false;
6237*8975f5c5SAndroid Build Coastguard Worker }
6238*8975f5c5SAndroid Build Coastguard Worker
6239*8975f5c5SAndroid Build Coastguard Worker // [EXT_geometry_shader] Chapter 7.12
6240*8975f5c5SAndroid Build Coastguard Worker // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
6241*8975f5c5SAndroid Build Coastguard Worker // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
6242*8975f5c5SAndroid Build Coastguard Worker // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
6243*8975f5c5SAndroid Build Coastguard Worker // successfully, or which does not contain objects to form a geometry shader.
6244*8975f5c5SAndroid Build Coastguard Worker if (!programObject->isLinked())
6245*8975f5c5SAndroid Build Coastguard Worker {
6246*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6247*8975f5c5SAndroid Build Coastguard Worker return false;
6248*8975f5c5SAndroid Build Coastguard Worker }
6249*8975f5c5SAndroid Build Coastguard Worker if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Geometry))
6250*8975f5c5SAndroid Build Coastguard Worker {
6251*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
6252*8975f5c5SAndroid Build Coastguard Worker return false;
6253*8975f5c5SAndroid Build Coastguard Worker }
6254*8975f5c5SAndroid Build Coastguard Worker break;
6255*8975f5c5SAndroid Build Coastguard Worker
6256*8975f5c5SAndroid Build Coastguard Worker case GL_COMPLETION_STATUS_KHR:
6257*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().parallelShaderCompileKHR)
6258*8975f5c5SAndroid Build Coastguard Worker {
6259*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6260*8975f5c5SAndroid Build Coastguard Worker return false;
6261*8975f5c5SAndroid Build Coastguard Worker }
6262*8975f5c5SAndroid Build Coastguard Worker break;
6263*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
6264*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_GEN_MODE_EXT:
6265*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_GEN_SPACING_EXT:
6266*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_GEN_VERTEX_ORDER_EXT:
6267*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_GEN_POINT_MODE_EXT:
6268*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().tessellationShaderAny() &&
6269*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
6270*8975f5c5SAndroid Build Coastguard Worker {
6271*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTessellationShaderEXTNotEnabled);
6272*8975f5c5SAndroid Build Coastguard Worker return false;
6273*8975f5c5SAndroid Build Coastguard Worker }
6274*8975f5c5SAndroid Build Coastguard Worker if (!programObject->isLinked())
6275*8975f5c5SAndroid Build Coastguard Worker {
6276*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6277*8975f5c5SAndroid Build Coastguard Worker return false;
6278*8975f5c5SAndroid Build Coastguard Worker }
6279*8975f5c5SAndroid Build Coastguard Worker break;
6280*8975f5c5SAndroid Build Coastguard Worker default:
6281*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6282*8975f5c5SAndroid Build Coastguard Worker return false;
6283*8975f5c5SAndroid Build Coastguard Worker }
6284*8975f5c5SAndroid Build Coastguard Worker
6285*8975f5c5SAndroid Build Coastguard Worker return true;
6286*8975f5c5SAndroid Build Coastguard Worker }
6287*8975f5c5SAndroid Build Coastguard Worker
ValidateGetProgramivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6288*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProgramivRobustANGLE(const Context *context,
6289*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6290*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
6291*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6292*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6293*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6294*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6295*8975f5c5SAndroid Build Coastguard Worker {
6296*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6297*8975f5c5SAndroid Build Coastguard Worker {
6298*8975f5c5SAndroid Build Coastguard Worker return false;
6299*8975f5c5SAndroid Build Coastguard Worker }
6300*8975f5c5SAndroid Build Coastguard Worker
6301*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6302*8975f5c5SAndroid Build Coastguard Worker
6303*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetProgramivBase(context, entryPoint, program, pname, &numParams))
6304*8975f5c5SAndroid Build Coastguard Worker {
6305*8975f5c5SAndroid Build Coastguard Worker return false;
6306*8975f5c5SAndroid Build Coastguard Worker }
6307*8975f5c5SAndroid Build Coastguard Worker
6308*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6309*8975f5c5SAndroid Build Coastguard Worker {
6310*8975f5c5SAndroid Build Coastguard Worker return false;
6311*8975f5c5SAndroid Build Coastguard Worker }
6312*8975f5c5SAndroid Build Coastguard Worker
6313*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6314*8975f5c5SAndroid Build Coastguard Worker
6315*8975f5c5SAndroid Build Coastguard Worker return true;
6316*8975f5c5SAndroid Build Coastguard Worker }
6317*8975f5c5SAndroid Build Coastguard Worker
ValidateGetRenderbufferParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6318*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetRenderbufferParameterivRobustANGLE(const Context *context,
6319*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6320*8975f5c5SAndroid Build Coastguard Worker GLenum target,
6321*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6322*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6323*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6324*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6325*8975f5c5SAndroid Build Coastguard Worker {
6326*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6327*8975f5c5SAndroid Build Coastguard Worker {
6328*8975f5c5SAndroid Build Coastguard Worker return false;
6329*8975f5c5SAndroid Build Coastguard Worker }
6330*8975f5c5SAndroid Build Coastguard Worker
6331*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6332*8975f5c5SAndroid Build Coastguard Worker
6333*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, &numParams))
6334*8975f5c5SAndroid Build Coastguard Worker {
6335*8975f5c5SAndroid Build Coastguard Worker return false;
6336*8975f5c5SAndroid Build Coastguard Worker }
6337*8975f5c5SAndroid Build Coastguard Worker
6338*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6339*8975f5c5SAndroid Build Coastguard Worker {
6340*8975f5c5SAndroid Build Coastguard Worker return false;
6341*8975f5c5SAndroid Build Coastguard Worker }
6342*8975f5c5SAndroid Build Coastguard Worker
6343*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6344*8975f5c5SAndroid Build Coastguard Worker
6345*8975f5c5SAndroid Build Coastguard Worker return true;
6346*8975f5c5SAndroid Build Coastguard Worker }
6347*8975f5c5SAndroid Build Coastguard Worker
ValidateGetShaderivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6348*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetShaderivRobustANGLE(const Context *context,
6349*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6350*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID shader,
6351*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6352*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6353*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6354*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6355*8975f5c5SAndroid Build Coastguard Worker {
6356*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6357*8975f5c5SAndroid Build Coastguard Worker {
6358*8975f5c5SAndroid Build Coastguard Worker return false;
6359*8975f5c5SAndroid Build Coastguard Worker }
6360*8975f5c5SAndroid Build Coastguard Worker
6361*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6362*8975f5c5SAndroid Build Coastguard Worker
6363*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetShaderivBase(context, entryPoint, shader, pname, &numParams))
6364*8975f5c5SAndroid Build Coastguard Worker {
6365*8975f5c5SAndroid Build Coastguard Worker return false;
6366*8975f5c5SAndroid Build Coastguard Worker }
6367*8975f5c5SAndroid Build Coastguard Worker
6368*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6369*8975f5c5SAndroid Build Coastguard Worker {
6370*8975f5c5SAndroid Build Coastguard Worker return false;
6371*8975f5c5SAndroid Build Coastguard Worker }
6372*8975f5c5SAndroid Build Coastguard Worker
6373*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6374*8975f5c5SAndroid Build Coastguard Worker
6375*8975f5c5SAndroid Build Coastguard Worker return true;
6376*8975f5c5SAndroid Build Coastguard Worker }
6377*8975f5c5SAndroid Build Coastguard Worker
ValidateGetTexParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)6378*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterfvRobustANGLE(const Context *context,
6379*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6380*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6381*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6382*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6383*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6384*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
6385*8975f5c5SAndroid Build Coastguard Worker {
6386*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6387*8975f5c5SAndroid Build Coastguard Worker {
6388*8975f5c5SAndroid Build Coastguard Worker return false;
6389*8975f5c5SAndroid Build Coastguard Worker }
6390*8975f5c5SAndroid Build Coastguard Worker
6391*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6392*8975f5c5SAndroid Build Coastguard Worker
6393*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams))
6394*8975f5c5SAndroid Build Coastguard Worker {
6395*8975f5c5SAndroid Build Coastguard Worker return false;
6396*8975f5c5SAndroid Build Coastguard Worker }
6397*8975f5c5SAndroid Build Coastguard Worker
6398*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6399*8975f5c5SAndroid Build Coastguard Worker {
6400*8975f5c5SAndroid Build Coastguard Worker return false;
6401*8975f5c5SAndroid Build Coastguard Worker }
6402*8975f5c5SAndroid Build Coastguard Worker
6403*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6404*8975f5c5SAndroid Build Coastguard Worker
6405*8975f5c5SAndroid Build Coastguard Worker return true;
6406*8975f5c5SAndroid Build Coastguard Worker }
6407*8975f5c5SAndroid Build Coastguard Worker
ValidateGetTexParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6408*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterivRobustANGLE(const Context *context,
6409*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6410*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6411*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6412*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6413*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6414*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6415*8975f5c5SAndroid Build Coastguard Worker {
6416*8975f5c5SAndroid Build Coastguard Worker
6417*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6418*8975f5c5SAndroid Build Coastguard Worker {
6419*8975f5c5SAndroid Build Coastguard Worker return false;
6420*8975f5c5SAndroid Build Coastguard Worker }
6421*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6422*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams))
6423*8975f5c5SAndroid Build Coastguard Worker {
6424*8975f5c5SAndroid Build Coastguard Worker return false;
6425*8975f5c5SAndroid Build Coastguard Worker }
6426*8975f5c5SAndroid Build Coastguard Worker
6427*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6428*8975f5c5SAndroid Build Coastguard Worker {
6429*8975f5c5SAndroid Build Coastguard Worker return false;
6430*8975f5c5SAndroid Build Coastguard Worker }
6431*8975f5c5SAndroid Build Coastguard Worker
6432*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6433*8975f5c5SAndroid Build Coastguard Worker return true;
6434*8975f5c5SAndroid Build Coastguard Worker }
6435*8975f5c5SAndroid Build Coastguard Worker
ValidateGetTexParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6436*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterIivRobustANGLE(const Context *context,
6437*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6438*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6439*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6440*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6441*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6442*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6443*8975f5c5SAndroid Build Coastguard Worker {
6444*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6445*8975f5c5SAndroid Build Coastguard Worker return false;
6446*8975f5c5SAndroid Build Coastguard Worker }
6447*8975f5c5SAndroid Build Coastguard Worker
ValidateGetTexParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)6448*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterIuivRobustANGLE(const Context *context,
6449*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6450*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6451*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6452*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6453*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6454*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
6455*8975f5c5SAndroid Build Coastguard Worker {
6456*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6457*8975f5c5SAndroid Build Coastguard Worker return false;
6458*8975f5c5SAndroid Build Coastguard Worker }
6459*8975f5c5SAndroid Build Coastguard Worker
ValidateTexParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLfloat * params)6460*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterfvRobustANGLE(const Context *context,
6461*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6462*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6463*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6464*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6465*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
6466*8975f5c5SAndroid Build Coastguard Worker {
6467*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6468*8975f5c5SAndroid Build Coastguard Worker {
6469*8975f5c5SAndroid Build Coastguard Worker return false;
6470*8975f5c5SAndroid Build Coastguard Worker }
6471*8975f5c5SAndroid Build Coastguard Worker
6472*8975f5c5SAndroid Build Coastguard Worker return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params);
6473*8975f5c5SAndroid Build Coastguard Worker }
6474*8975f5c5SAndroid Build Coastguard Worker
ValidateTexParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)6475*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterivRobustANGLE(const Context *context,
6476*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6477*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6478*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6479*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6480*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6481*8975f5c5SAndroid Build Coastguard Worker {
6482*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6483*8975f5c5SAndroid Build Coastguard Worker {
6484*8975f5c5SAndroid Build Coastguard Worker return false;
6485*8975f5c5SAndroid Build Coastguard Worker }
6486*8975f5c5SAndroid Build Coastguard Worker
6487*8975f5c5SAndroid Build Coastguard Worker return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params);
6488*8975f5c5SAndroid Build Coastguard Worker }
6489*8975f5c5SAndroid Build Coastguard Worker
ValidateTexParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)6490*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterIivRobustANGLE(const Context *context,
6491*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6492*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6493*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6494*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6495*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6496*8975f5c5SAndroid Build Coastguard Worker {
6497*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6498*8975f5c5SAndroid Build Coastguard Worker return false;
6499*8975f5c5SAndroid Build Coastguard Worker }
6500*8975f5c5SAndroid Build Coastguard Worker
ValidateTexParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLuint * params)6501*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterIuivRobustANGLE(const Context *context,
6502*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6503*8975f5c5SAndroid Build Coastguard Worker TextureType target,
6504*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6505*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6506*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
6507*8975f5c5SAndroid Build Coastguard Worker {
6508*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6509*8975f5c5SAndroid Build Coastguard Worker return false;
6510*8975f5c5SAndroid Build Coastguard Worker }
6511*8975f5c5SAndroid Build Coastguard Worker
ValidateGetSamplerParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)6512*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterfvRobustANGLE(const Context *context,
6513*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6514*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6515*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6516*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6517*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6518*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
6519*8975f5c5SAndroid Build Coastguard Worker {
6520*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6521*8975f5c5SAndroid Build Coastguard Worker {
6522*8975f5c5SAndroid Build Coastguard Worker return false;
6523*8975f5c5SAndroid Build Coastguard Worker }
6524*8975f5c5SAndroid Build Coastguard Worker
6525*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6526*8975f5c5SAndroid Build Coastguard Worker
6527*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams))
6528*8975f5c5SAndroid Build Coastguard Worker {
6529*8975f5c5SAndroid Build Coastguard Worker return false;
6530*8975f5c5SAndroid Build Coastguard Worker }
6531*8975f5c5SAndroid Build Coastguard Worker
6532*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6533*8975f5c5SAndroid Build Coastguard Worker {
6534*8975f5c5SAndroid Build Coastguard Worker return false;
6535*8975f5c5SAndroid Build Coastguard Worker }
6536*8975f5c5SAndroid Build Coastguard Worker
6537*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6538*8975f5c5SAndroid Build Coastguard Worker return true;
6539*8975f5c5SAndroid Build Coastguard Worker }
6540*8975f5c5SAndroid Build Coastguard Worker
ValidateGetSamplerParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6541*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterivRobustANGLE(const Context *context,
6542*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6543*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6544*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6545*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6546*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6547*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6548*8975f5c5SAndroid Build Coastguard Worker {
6549*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6550*8975f5c5SAndroid Build Coastguard Worker {
6551*8975f5c5SAndroid Build Coastguard Worker return false;
6552*8975f5c5SAndroid Build Coastguard Worker }
6553*8975f5c5SAndroid Build Coastguard Worker
6554*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6555*8975f5c5SAndroid Build Coastguard Worker
6556*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams))
6557*8975f5c5SAndroid Build Coastguard Worker {
6558*8975f5c5SAndroid Build Coastguard Worker return false;
6559*8975f5c5SAndroid Build Coastguard Worker }
6560*8975f5c5SAndroid Build Coastguard Worker
6561*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6562*8975f5c5SAndroid Build Coastguard Worker {
6563*8975f5c5SAndroid Build Coastguard Worker return false;
6564*8975f5c5SAndroid Build Coastguard Worker }
6565*8975f5c5SAndroid Build Coastguard Worker
6566*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6567*8975f5c5SAndroid Build Coastguard Worker return true;
6568*8975f5c5SAndroid Build Coastguard Worker }
6569*8975f5c5SAndroid Build Coastguard Worker
ValidateGetSamplerParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6570*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterIivRobustANGLE(const Context *context,
6571*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6572*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6573*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6574*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6575*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6576*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6577*8975f5c5SAndroid Build Coastguard Worker {
6578*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6579*8975f5c5SAndroid Build Coastguard Worker return false;
6580*8975f5c5SAndroid Build Coastguard Worker }
6581*8975f5c5SAndroid Build Coastguard Worker
ValidateGetSamplerParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)6582*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterIuivRobustANGLE(const Context *context,
6583*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6584*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6585*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6586*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6587*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6588*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
6589*8975f5c5SAndroid Build Coastguard Worker {
6590*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6591*8975f5c5SAndroid Build Coastguard Worker return false;
6592*8975f5c5SAndroid Build Coastguard Worker }
6593*8975f5c5SAndroid Build Coastguard Worker
ValidateSamplerParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLfloat * params)6594*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterfvRobustANGLE(const Context *context,
6595*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6596*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6597*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6598*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6599*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
6600*8975f5c5SAndroid Build Coastguard Worker {
6601*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6602*8975f5c5SAndroid Build Coastguard Worker {
6603*8975f5c5SAndroid Build Coastguard Worker return false;
6604*8975f5c5SAndroid Build Coastguard Worker }
6605*8975f5c5SAndroid Build Coastguard Worker
6606*8975f5c5SAndroid Build Coastguard Worker return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params);
6607*8975f5c5SAndroid Build Coastguard Worker }
6608*8975f5c5SAndroid Build Coastguard Worker
ValidateSamplerParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * params)6609*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterivRobustANGLE(const Context *context,
6610*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6611*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6612*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6613*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6614*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6615*8975f5c5SAndroid Build Coastguard Worker {
6616*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6617*8975f5c5SAndroid Build Coastguard Worker {
6618*8975f5c5SAndroid Build Coastguard Worker return false;
6619*8975f5c5SAndroid Build Coastguard Worker }
6620*8975f5c5SAndroid Build Coastguard Worker
6621*8975f5c5SAndroid Build Coastguard Worker return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params);
6622*8975f5c5SAndroid Build Coastguard Worker }
6623*8975f5c5SAndroid Build Coastguard Worker
ValidateSamplerParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * param)6624*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterIivRobustANGLE(const Context *context,
6625*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6626*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6627*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6628*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6629*8975f5c5SAndroid Build Coastguard Worker const GLint *param)
6630*8975f5c5SAndroid Build Coastguard Worker {
6631*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6632*8975f5c5SAndroid Build Coastguard Worker return false;
6633*8975f5c5SAndroid Build Coastguard Worker }
6634*8975f5c5SAndroid Build Coastguard Worker
ValidateSamplerParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLuint * param)6635*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterIuivRobustANGLE(const Context *context,
6636*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6637*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
6638*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6639*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6640*8975f5c5SAndroid Build Coastguard Worker const GLuint *param)
6641*8975f5c5SAndroid Build Coastguard Worker {
6642*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
6643*8975f5c5SAndroid Build Coastguard Worker return false;
6644*8975f5c5SAndroid Build Coastguard Worker }
6645*8975f5c5SAndroid Build Coastguard Worker
ValidateGetVertexAttribfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)6646*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribfvRobustANGLE(const Context *context,
6647*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6648*8975f5c5SAndroid Build Coastguard Worker GLuint index,
6649*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6650*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6651*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6652*8975f5c5SAndroid Build Coastguard Worker const GLfloat *params)
6653*8975f5c5SAndroid Build Coastguard Worker {
6654*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6655*8975f5c5SAndroid Build Coastguard Worker {
6656*8975f5c5SAndroid Build Coastguard Worker return false;
6657*8975f5c5SAndroid Build Coastguard Worker }
6658*8975f5c5SAndroid Build Coastguard Worker
6659*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
6660*8975f5c5SAndroid Build Coastguard Worker
6661*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false))
6662*8975f5c5SAndroid Build Coastguard Worker {
6663*8975f5c5SAndroid Build Coastguard Worker return false;
6664*8975f5c5SAndroid Build Coastguard Worker }
6665*8975f5c5SAndroid Build Coastguard Worker
6666*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6667*8975f5c5SAndroid Build Coastguard Worker {
6668*8975f5c5SAndroid Build Coastguard Worker return false;
6669*8975f5c5SAndroid Build Coastguard Worker }
6670*8975f5c5SAndroid Build Coastguard Worker
6671*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
6672*8975f5c5SAndroid Build Coastguard Worker return true;
6673*8975f5c5SAndroid Build Coastguard Worker }
6674*8975f5c5SAndroid Build Coastguard Worker
ValidateGetVertexAttribivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6675*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribivRobustANGLE(const Context *context,
6676*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6677*8975f5c5SAndroid Build Coastguard Worker GLuint index,
6678*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6679*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6680*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6681*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6682*8975f5c5SAndroid Build Coastguard Worker {
6683*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6684*8975f5c5SAndroid Build Coastguard Worker {
6685*8975f5c5SAndroid Build Coastguard Worker return false;
6686*8975f5c5SAndroid Build Coastguard Worker }
6687*8975f5c5SAndroid Build Coastguard Worker
6688*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
6689*8975f5c5SAndroid Build Coastguard Worker
6690*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false))
6691*8975f5c5SAndroid Build Coastguard Worker {
6692*8975f5c5SAndroid Build Coastguard Worker return false;
6693*8975f5c5SAndroid Build Coastguard Worker }
6694*8975f5c5SAndroid Build Coastguard Worker
6695*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6696*8975f5c5SAndroid Build Coastguard Worker {
6697*8975f5c5SAndroid Build Coastguard Worker return false;
6698*8975f5c5SAndroid Build Coastguard Worker }
6699*8975f5c5SAndroid Build Coastguard Worker
6700*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
6701*8975f5c5SAndroid Build Coastguard Worker
6702*8975f5c5SAndroid Build Coastguard Worker return true;
6703*8975f5c5SAndroid Build Coastguard Worker }
6704*8975f5c5SAndroid Build Coastguard Worker
ValidateGetVertexAttribPointervRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,void * const * pointer)6705*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribPointervRobustANGLE(const Context *context,
6706*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6707*8975f5c5SAndroid Build Coastguard Worker GLuint index,
6708*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6709*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6710*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6711*8975f5c5SAndroid Build Coastguard Worker void *const *pointer)
6712*8975f5c5SAndroid Build Coastguard Worker {
6713*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6714*8975f5c5SAndroid Build Coastguard Worker {
6715*8975f5c5SAndroid Build Coastguard Worker return false;
6716*8975f5c5SAndroid Build Coastguard Worker }
6717*8975f5c5SAndroid Build Coastguard Worker
6718*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
6719*8975f5c5SAndroid Build Coastguard Worker
6720*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, true, false))
6721*8975f5c5SAndroid Build Coastguard Worker {
6722*8975f5c5SAndroid Build Coastguard Worker return false;
6723*8975f5c5SAndroid Build Coastguard Worker }
6724*8975f5c5SAndroid Build Coastguard Worker
6725*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6726*8975f5c5SAndroid Build Coastguard Worker {
6727*8975f5c5SAndroid Build Coastguard Worker return false;
6728*8975f5c5SAndroid Build Coastguard Worker }
6729*8975f5c5SAndroid Build Coastguard Worker
6730*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
6731*8975f5c5SAndroid Build Coastguard Worker
6732*8975f5c5SAndroid Build Coastguard Worker return true;
6733*8975f5c5SAndroid Build Coastguard Worker }
6734*8975f5c5SAndroid Build Coastguard Worker
ValidateGetVertexAttribIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6735*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribIivRobustANGLE(const Context *context,
6736*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6737*8975f5c5SAndroid Build Coastguard Worker GLuint index,
6738*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6739*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6740*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6741*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6742*8975f5c5SAndroid Build Coastguard Worker {
6743*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6744*8975f5c5SAndroid Build Coastguard Worker {
6745*8975f5c5SAndroid Build Coastguard Worker return false;
6746*8975f5c5SAndroid Build Coastguard Worker }
6747*8975f5c5SAndroid Build Coastguard Worker
6748*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
6749*8975f5c5SAndroid Build Coastguard Worker
6750*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true))
6751*8975f5c5SAndroid Build Coastguard Worker {
6752*8975f5c5SAndroid Build Coastguard Worker return false;
6753*8975f5c5SAndroid Build Coastguard Worker }
6754*8975f5c5SAndroid Build Coastguard Worker
6755*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6756*8975f5c5SAndroid Build Coastguard Worker {
6757*8975f5c5SAndroid Build Coastguard Worker return false;
6758*8975f5c5SAndroid Build Coastguard Worker }
6759*8975f5c5SAndroid Build Coastguard Worker
6760*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
6761*8975f5c5SAndroid Build Coastguard Worker
6762*8975f5c5SAndroid Build Coastguard Worker return true;
6763*8975f5c5SAndroid Build Coastguard Worker }
6764*8975f5c5SAndroid Build Coastguard Worker
ValidateGetVertexAttribIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)6765*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribIuivRobustANGLE(const Context *context,
6766*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6767*8975f5c5SAndroid Build Coastguard Worker GLuint index,
6768*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6769*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6770*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6771*8975f5c5SAndroid Build Coastguard Worker const GLuint *params)
6772*8975f5c5SAndroid Build Coastguard Worker {
6773*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6774*8975f5c5SAndroid Build Coastguard Worker {
6775*8975f5c5SAndroid Build Coastguard Worker return false;
6776*8975f5c5SAndroid Build Coastguard Worker }
6777*8975f5c5SAndroid Build Coastguard Worker
6778*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
6779*8975f5c5SAndroid Build Coastguard Worker
6780*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true))
6781*8975f5c5SAndroid Build Coastguard Worker {
6782*8975f5c5SAndroid Build Coastguard Worker return false;
6783*8975f5c5SAndroid Build Coastguard Worker }
6784*8975f5c5SAndroid Build Coastguard Worker
6785*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6786*8975f5c5SAndroid Build Coastguard Worker {
6787*8975f5c5SAndroid Build Coastguard Worker return false;
6788*8975f5c5SAndroid Build Coastguard Worker }
6789*8975f5c5SAndroid Build Coastguard Worker
6790*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
6791*8975f5c5SAndroid Build Coastguard Worker
6792*8975f5c5SAndroid Build Coastguard Worker return true;
6793*8975f5c5SAndroid Build Coastguard Worker }
6794*8975f5c5SAndroid Build Coastguard Worker
ValidateGetActiveUniformBlockivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6795*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetActiveUniformBlockivRobustANGLE(const Context *context,
6796*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6797*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
6798*8975f5c5SAndroid Build Coastguard Worker UniformBlockIndex uniformBlockIndex,
6799*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6800*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6801*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6802*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6803*8975f5c5SAndroid Build Coastguard Worker {
6804*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6805*8975f5c5SAndroid Build Coastguard Worker {
6806*8975f5c5SAndroid Build Coastguard Worker return false;
6807*8975f5c5SAndroid Build Coastguard Worker }
6808*8975f5c5SAndroid Build Coastguard Worker
6809*8975f5c5SAndroid Build Coastguard Worker GLsizei writeLength = 0;
6810*8975f5c5SAndroid Build Coastguard Worker
6811*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex, pname,
6812*8975f5c5SAndroid Build Coastguard Worker &writeLength))
6813*8975f5c5SAndroid Build Coastguard Worker {
6814*8975f5c5SAndroid Build Coastguard Worker return false;
6815*8975f5c5SAndroid Build Coastguard Worker }
6816*8975f5c5SAndroid Build Coastguard Worker
6817*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6818*8975f5c5SAndroid Build Coastguard Worker {
6819*8975f5c5SAndroid Build Coastguard Worker return false;
6820*8975f5c5SAndroid Build Coastguard Worker }
6821*8975f5c5SAndroid Build Coastguard Worker
6822*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, writeLength);
6823*8975f5c5SAndroid Build Coastguard Worker
6824*8975f5c5SAndroid Build Coastguard Worker return true;
6825*8975f5c5SAndroid Build Coastguard Worker }
6826*8975f5c5SAndroid Build Coastguard Worker
ValidateGetInternalformativRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6827*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetInternalformativRobustANGLE(const Context *context,
6828*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6829*8975f5c5SAndroid Build Coastguard Worker GLenum target,
6830*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
6831*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6832*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
6833*8975f5c5SAndroid Build Coastguard Worker const GLsizei *length,
6834*8975f5c5SAndroid Build Coastguard Worker const GLint *params)
6835*8975f5c5SAndroid Build Coastguard Worker {
6836*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6837*8975f5c5SAndroid Build Coastguard Worker {
6838*8975f5c5SAndroid Build Coastguard Worker return false;
6839*8975f5c5SAndroid Build Coastguard Worker }
6840*8975f5c5SAndroid Build Coastguard Worker
6841*8975f5c5SAndroid Build Coastguard Worker GLsizei numParams = 0;
6842*8975f5c5SAndroid Build Coastguard Worker
6843*8975f5c5SAndroid Build Coastguard Worker if (!ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname,
6844*8975f5c5SAndroid Build Coastguard Worker bufSize, &numParams))
6845*8975f5c5SAndroid Build Coastguard Worker {
6846*8975f5c5SAndroid Build Coastguard Worker return false;
6847*8975f5c5SAndroid Build Coastguard Worker }
6848*8975f5c5SAndroid Build Coastguard Worker
6849*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6850*8975f5c5SAndroid Build Coastguard Worker {
6851*8975f5c5SAndroid Build Coastguard Worker return false;
6852*8975f5c5SAndroid Build Coastguard Worker }
6853*8975f5c5SAndroid Build Coastguard Worker
6854*8975f5c5SAndroid Build Coastguard Worker SetRobustLengthParam(length, numParams);
6855*8975f5c5SAndroid Build Coastguard Worker
6856*8975f5c5SAndroid Build Coastguard Worker return true;
6857*8975f5c5SAndroid Build Coastguard Worker }
6858*8975f5c5SAndroid Build Coastguard Worker
ValidateRobustCompressedTexImageBase(const Context * context,angle::EntryPoint entryPoint,GLsizei imageSize,GLsizei dataSize)6859*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustCompressedTexImageBase(const Context *context,
6860*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6861*8975f5c5SAndroid Build Coastguard Worker GLsizei imageSize,
6862*8975f5c5SAndroid Build Coastguard Worker GLsizei dataSize)
6863*8975f5c5SAndroid Build Coastguard Worker {
6864*8975f5c5SAndroid Build Coastguard Worker if (!ValidateRobustEntryPoint(context, entryPoint, dataSize))
6865*8975f5c5SAndroid Build Coastguard Worker {
6866*8975f5c5SAndroid Build Coastguard Worker return false;
6867*8975f5c5SAndroid Build Coastguard Worker }
6868*8975f5c5SAndroid Build Coastguard Worker
6869*8975f5c5SAndroid Build Coastguard Worker Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
6870*8975f5c5SAndroid Build Coastguard Worker if (pixelUnpackBuffer == nullptr)
6871*8975f5c5SAndroid Build Coastguard Worker {
6872*8975f5c5SAndroid Build Coastguard Worker if (dataSize < imageSize)
6873*8975f5c5SAndroid Build Coastguard Worker {
6874*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
6875*8975f5c5SAndroid Build Coastguard Worker }
6876*8975f5c5SAndroid Build Coastguard Worker }
6877*8975f5c5SAndroid Build Coastguard Worker return true;
6878*8975f5c5SAndroid Build Coastguard Worker }
6879*8975f5c5SAndroid Build Coastguard Worker
ValidateGetBufferParameterBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,bool pointerVersion,GLsizei * numParams)6880*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferParameterBase(const Context *context,
6881*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6882*8975f5c5SAndroid Build Coastguard Worker BufferBinding target,
6883*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6884*8975f5c5SAndroid Build Coastguard Worker bool pointerVersion,
6885*8975f5c5SAndroid Build Coastguard Worker GLsizei *numParams)
6886*8975f5c5SAndroid Build Coastguard Worker {
6887*8975f5c5SAndroid Build Coastguard Worker if (numParams)
6888*8975f5c5SAndroid Build Coastguard Worker {
6889*8975f5c5SAndroid Build Coastguard Worker *numParams = 0;
6890*8975f5c5SAndroid Build Coastguard Worker }
6891*8975f5c5SAndroid Build Coastguard Worker
6892*8975f5c5SAndroid Build Coastguard Worker if (!context->isValidBufferBinding(target))
6893*8975f5c5SAndroid Build Coastguard Worker {
6894*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
6895*8975f5c5SAndroid Build Coastguard Worker return false;
6896*8975f5c5SAndroid Build Coastguard Worker }
6897*8975f5c5SAndroid Build Coastguard Worker
6898*8975f5c5SAndroid Build Coastguard Worker const Buffer *buffer = context->getState().getTargetBuffer(target);
6899*8975f5c5SAndroid Build Coastguard Worker if (!buffer)
6900*8975f5c5SAndroid Build Coastguard Worker {
6901*8975f5c5SAndroid Build Coastguard Worker // A null buffer means that "0" is bound to the requested buffer target
6902*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
6903*8975f5c5SAndroid Build Coastguard Worker return false;
6904*8975f5c5SAndroid Build Coastguard Worker }
6905*8975f5c5SAndroid Build Coastguard Worker
6906*8975f5c5SAndroid Build Coastguard Worker const Extensions &extensions = context->getExtensions();
6907*8975f5c5SAndroid Build Coastguard Worker
6908*8975f5c5SAndroid Build Coastguard Worker switch (pname)
6909*8975f5c5SAndroid Build Coastguard Worker {
6910*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_USAGE:
6911*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_SIZE:
6912*8975f5c5SAndroid Build Coastguard Worker break;
6913*8975f5c5SAndroid Build Coastguard Worker
6914*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_ACCESS_OES:
6915*8975f5c5SAndroid Build Coastguard Worker if (!extensions.mapbufferOES)
6916*8975f5c5SAndroid Build Coastguard Worker {
6917*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6918*8975f5c5SAndroid Build Coastguard Worker return false;
6919*8975f5c5SAndroid Build Coastguard Worker }
6920*8975f5c5SAndroid Build Coastguard Worker break;
6921*8975f5c5SAndroid Build Coastguard Worker
6922*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_MAPPED:
6923*8975f5c5SAndroid Build Coastguard Worker static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
6924*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 && !extensions.mapbufferOES &&
6925*8975f5c5SAndroid Build Coastguard Worker !extensions.mapBufferRangeEXT)
6926*8975f5c5SAndroid Build Coastguard Worker {
6927*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6928*8975f5c5SAndroid Build Coastguard Worker return false;
6929*8975f5c5SAndroid Build Coastguard Worker }
6930*8975f5c5SAndroid Build Coastguard Worker break;
6931*8975f5c5SAndroid Build Coastguard Worker
6932*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_MAP_POINTER:
6933*8975f5c5SAndroid Build Coastguard Worker if (!pointerVersion)
6934*8975f5c5SAndroid Build Coastguard Worker {
6935*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMapPointerQuery);
6936*8975f5c5SAndroid Build Coastguard Worker return false;
6937*8975f5c5SAndroid Build Coastguard Worker }
6938*8975f5c5SAndroid Build Coastguard Worker break;
6939*8975f5c5SAndroid Build Coastguard Worker
6940*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_ACCESS_FLAGS:
6941*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_MAP_OFFSET:
6942*8975f5c5SAndroid Build Coastguard Worker case GL_BUFFER_MAP_LENGTH:
6943*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRangeEXT)
6944*8975f5c5SAndroid Build Coastguard Worker {
6945*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6946*8975f5c5SAndroid Build Coastguard Worker return false;
6947*8975f5c5SAndroid Build Coastguard Worker }
6948*8975f5c5SAndroid Build Coastguard Worker break;
6949*8975f5c5SAndroid Build Coastguard Worker
6950*8975f5c5SAndroid Build Coastguard Worker case GL_MEMORY_SIZE_ANGLE:
6951*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().memorySizeANGLE)
6952*8975f5c5SAndroid Build Coastguard Worker {
6953*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
6954*8975f5c5SAndroid Build Coastguard Worker return false;
6955*8975f5c5SAndroid Build Coastguard Worker }
6956*8975f5c5SAndroid Build Coastguard Worker break;
6957*8975f5c5SAndroid Build Coastguard Worker
6958*8975f5c5SAndroid Build Coastguard Worker case GL_RESOURCE_INITIALIZED_ANGLE:
6959*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().robustResourceInitializationANGLE)
6960*8975f5c5SAndroid Build Coastguard Worker {
6961*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
6962*8975f5c5SAndroid Build Coastguard Worker kRobustResourceInitializationExtensionRequired);
6963*8975f5c5SAndroid Build Coastguard Worker return false;
6964*8975f5c5SAndroid Build Coastguard Worker }
6965*8975f5c5SAndroid Build Coastguard Worker break;
6966*8975f5c5SAndroid Build Coastguard Worker
6967*8975f5c5SAndroid Build Coastguard Worker default:
6968*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6969*8975f5c5SAndroid Build Coastguard Worker return false;
6970*8975f5c5SAndroid Build Coastguard Worker }
6971*8975f5c5SAndroid Build Coastguard Worker
6972*8975f5c5SAndroid Build Coastguard Worker // All buffer parameter queries return one value.
6973*8975f5c5SAndroid Build Coastguard Worker if (numParams)
6974*8975f5c5SAndroid Build Coastguard Worker {
6975*8975f5c5SAndroid Build Coastguard Worker *numParams = 1;
6976*8975f5c5SAndroid Build Coastguard Worker }
6977*8975f5c5SAndroid Build Coastguard Worker
6978*8975f5c5SAndroid Build Coastguard Worker return true;
6979*8975f5c5SAndroid Build Coastguard Worker }
6980*8975f5c5SAndroid Build Coastguard Worker
ValidateGetRenderbufferParameterivBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLsizei * length)6981*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetRenderbufferParameterivBase(const Context *context,
6982*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
6983*8975f5c5SAndroid Build Coastguard Worker GLenum target,
6984*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
6985*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
6986*8975f5c5SAndroid Build Coastguard Worker {
6987*8975f5c5SAndroid Build Coastguard Worker if (length)
6988*8975f5c5SAndroid Build Coastguard Worker {
6989*8975f5c5SAndroid Build Coastguard Worker *length = 0;
6990*8975f5c5SAndroid Build Coastguard Worker }
6991*8975f5c5SAndroid Build Coastguard Worker
6992*8975f5c5SAndroid Build Coastguard Worker if (target != GL_RENDERBUFFER)
6993*8975f5c5SAndroid Build Coastguard Worker {
6994*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
6995*8975f5c5SAndroid Build Coastguard Worker return false;
6996*8975f5c5SAndroid Build Coastguard Worker }
6997*8975f5c5SAndroid Build Coastguard Worker
6998*8975f5c5SAndroid Build Coastguard Worker Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
6999*8975f5c5SAndroid Build Coastguard Worker if (renderbuffer == nullptr)
7000*8975f5c5SAndroid Build Coastguard Worker {
7001*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kRenderbufferNotBound);
7002*8975f5c5SAndroid Build Coastguard Worker return false;
7003*8975f5c5SAndroid Build Coastguard Worker }
7004*8975f5c5SAndroid Build Coastguard Worker
7005*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7006*8975f5c5SAndroid Build Coastguard Worker {
7007*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_WIDTH:
7008*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_HEIGHT:
7009*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_INTERNAL_FORMAT:
7010*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_RED_SIZE:
7011*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_GREEN_SIZE:
7012*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_BLUE_SIZE:
7013*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_ALPHA_SIZE:
7014*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_DEPTH_SIZE:
7015*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_STENCIL_SIZE:
7016*8975f5c5SAndroid Build Coastguard Worker break;
7017*8975f5c5SAndroid Build Coastguard Worker
7018*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER_SAMPLES_ANGLE:
7019*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 &&
7020*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().framebufferMultisampleANGLE)
7021*8975f5c5SAndroid Build Coastguard Worker {
7022*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7023*8975f5c5SAndroid Build Coastguard Worker return false;
7024*8975f5c5SAndroid Build Coastguard Worker }
7025*8975f5c5SAndroid Build Coastguard Worker break;
7026*8975f5c5SAndroid Build Coastguard Worker
7027*8975f5c5SAndroid Build Coastguard Worker case GL_MEMORY_SIZE_ANGLE:
7028*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().memorySizeANGLE)
7029*8975f5c5SAndroid Build Coastguard Worker {
7030*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7031*8975f5c5SAndroid Build Coastguard Worker return false;
7032*8975f5c5SAndroid Build Coastguard Worker }
7033*8975f5c5SAndroid Build Coastguard Worker break;
7034*8975f5c5SAndroid Build Coastguard Worker
7035*8975f5c5SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
7036*8975f5c5SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_TYPE:
7037*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().getImageANGLE)
7038*8975f5c5SAndroid Build Coastguard Worker {
7039*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGetImageExtensionNotEnabled);
7040*8975f5c5SAndroid Build Coastguard Worker return false;
7041*8975f5c5SAndroid Build Coastguard Worker }
7042*8975f5c5SAndroid Build Coastguard Worker break;
7043*8975f5c5SAndroid Build Coastguard Worker
7044*8975f5c5SAndroid Build Coastguard Worker case GL_RESOURCE_INITIALIZED_ANGLE:
7045*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().robustResourceInitializationANGLE)
7046*8975f5c5SAndroid Build Coastguard Worker {
7047*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
7048*8975f5c5SAndroid Build Coastguard Worker kRobustResourceInitializationExtensionRequired);
7049*8975f5c5SAndroid Build Coastguard Worker return false;
7050*8975f5c5SAndroid Build Coastguard Worker }
7051*8975f5c5SAndroid Build Coastguard Worker break;
7052*8975f5c5SAndroid Build Coastguard Worker
7053*8975f5c5SAndroid Build Coastguard Worker default:
7054*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7055*8975f5c5SAndroid Build Coastguard Worker return false;
7056*8975f5c5SAndroid Build Coastguard Worker }
7057*8975f5c5SAndroid Build Coastguard Worker
7058*8975f5c5SAndroid Build Coastguard Worker if (length)
7059*8975f5c5SAndroid Build Coastguard Worker {
7060*8975f5c5SAndroid Build Coastguard Worker *length = 1;
7061*8975f5c5SAndroid Build Coastguard Worker }
7062*8975f5c5SAndroid Build Coastguard Worker return true;
7063*8975f5c5SAndroid Build Coastguard Worker }
7064*8975f5c5SAndroid Build Coastguard Worker
ValidateGetShaderivBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLenum pname,GLsizei * length)7065*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetShaderivBase(const Context *context,
7066*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
7067*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID shader,
7068*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
7069*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
7070*8975f5c5SAndroid Build Coastguard Worker {
7071*8975f5c5SAndroid Build Coastguard Worker if (length)
7072*8975f5c5SAndroid Build Coastguard Worker {
7073*8975f5c5SAndroid Build Coastguard Worker *length = 0;
7074*8975f5c5SAndroid Build Coastguard Worker }
7075*8975f5c5SAndroid Build Coastguard Worker
7076*8975f5c5SAndroid Build Coastguard Worker if (context->isContextLost())
7077*8975f5c5SAndroid Build Coastguard Worker {
7078*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
7079*8975f5c5SAndroid Build Coastguard Worker
7080*8975f5c5SAndroid Build Coastguard Worker if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR)
7081*8975f5c5SAndroid Build Coastguard Worker {
7082*8975f5c5SAndroid Build Coastguard Worker // Generate an error but still return true, the context still needs to return a
7083*8975f5c5SAndroid Build Coastguard Worker // value in this case.
7084*8975f5c5SAndroid Build Coastguard Worker return true;
7085*8975f5c5SAndroid Build Coastguard Worker }
7086*8975f5c5SAndroid Build Coastguard Worker else
7087*8975f5c5SAndroid Build Coastguard Worker {
7088*8975f5c5SAndroid Build Coastguard Worker return false;
7089*8975f5c5SAndroid Build Coastguard Worker }
7090*8975f5c5SAndroid Build Coastguard Worker }
7091*8975f5c5SAndroid Build Coastguard Worker
7092*8975f5c5SAndroid Build Coastguard Worker if (GetValidShader(context, entryPoint, shader) == nullptr)
7093*8975f5c5SAndroid Build Coastguard Worker {
7094*8975f5c5SAndroid Build Coastguard Worker return false;
7095*8975f5c5SAndroid Build Coastguard Worker }
7096*8975f5c5SAndroid Build Coastguard Worker
7097*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7098*8975f5c5SAndroid Build Coastguard Worker {
7099*8975f5c5SAndroid Build Coastguard Worker case GL_SHADER_TYPE:
7100*8975f5c5SAndroid Build Coastguard Worker case GL_DELETE_STATUS:
7101*8975f5c5SAndroid Build Coastguard Worker case GL_COMPILE_STATUS:
7102*8975f5c5SAndroid Build Coastguard Worker case GL_INFO_LOG_LENGTH:
7103*8975f5c5SAndroid Build Coastguard Worker case GL_SHADER_SOURCE_LENGTH:
7104*8975f5c5SAndroid Build Coastguard Worker break;
7105*8975f5c5SAndroid Build Coastguard Worker
7106*8975f5c5SAndroid Build Coastguard Worker case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7107*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().translatedShaderSourceANGLE)
7108*8975f5c5SAndroid Build Coastguard Worker {
7109*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7110*8975f5c5SAndroid Build Coastguard Worker return false;
7111*8975f5c5SAndroid Build Coastguard Worker }
7112*8975f5c5SAndroid Build Coastguard Worker break;
7113*8975f5c5SAndroid Build Coastguard Worker
7114*8975f5c5SAndroid Build Coastguard Worker case GL_COMPLETION_STATUS_KHR:
7115*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().parallelShaderCompileKHR)
7116*8975f5c5SAndroid Build Coastguard Worker {
7117*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
7118*8975f5c5SAndroid Build Coastguard Worker return false;
7119*8975f5c5SAndroid Build Coastguard Worker }
7120*8975f5c5SAndroid Build Coastguard Worker break;
7121*8975f5c5SAndroid Build Coastguard Worker
7122*8975f5c5SAndroid Build Coastguard Worker default:
7123*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7124*8975f5c5SAndroid Build Coastguard Worker return false;
7125*8975f5c5SAndroid Build Coastguard Worker }
7126*8975f5c5SAndroid Build Coastguard Worker
7127*8975f5c5SAndroid Build Coastguard Worker if (length)
7128*8975f5c5SAndroid Build Coastguard Worker {
7129*8975f5c5SAndroid Build Coastguard Worker *length = 1;
7130*8975f5c5SAndroid Build Coastguard Worker }
7131*8975f5c5SAndroid Build Coastguard Worker return true;
7132*8975f5c5SAndroid Build Coastguard Worker }
7133*8975f5c5SAndroid Build Coastguard Worker
ValidateGetTexParameterBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei * length)7134*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterBase(const Context *context,
7135*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
7136*8975f5c5SAndroid Build Coastguard Worker TextureType target,
7137*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
7138*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
7139*8975f5c5SAndroid Build Coastguard Worker {
7140*8975f5c5SAndroid Build Coastguard Worker if (length)
7141*8975f5c5SAndroid Build Coastguard Worker {
7142*8975f5c5SAndroid Build Coastguard Worker *length = 0;
7143*8975f5c5SAndroid Build Coastguard Worker }
7144*8975f5c5SAndroid Build Coastguard Worker
7145*8975f5c5SAndroid Build Coastguard Worker if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) ||
7146*8975f5c5SAndroid Build Coastguard Worker target == TextureType::Buffer)
7147*8975f5c5SAndroid Build Coastguard Worker {
7148*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
7149*8975f5c5SAndroid Build Coastguard Worker return false;
7150*8975f5c5SAndroid Build Coastguard Worker }
7151*8975f5c5SAndroid Build Coastguard Worker
7152*8975f5c5SAndroid Build Coastguard Worker if (context->getTextureByType(target) == nullptr)
7153*8975f5c5SAndroid Build Coastguard Worker {
7154*8975f5c5SAndroid Build Coastguard Worker // Should only be possible for external textures
7155*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureNotBound);
7156*8975f5c5SAndroid Build Coastguard Worker return false;
7157*8975f5c5SAndroid Build Coastguard Worker }
7158*8975f5c5SAndroid Build Coastguard Worker
7159*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
7160*8975f5c5SAndroid Build Coastguard Worker {
7161*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7162*8975f5c5SAndroid Build Coastguard Worker return false;
7163*8975f5c5SAndroid Build Coastguard Worker }
7164*8975f5c5SAndroid Build Coastguard Worker
7165*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7166*8975f5c5SAndroid Build Coastguard Worker {
7167*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAG_FILTER:
7168*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_FILTER:
7169*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_S:
7170*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_T:
7171*8975f5c5SAndroid Build Coastguard Worker break;
7172*8975f5c5SAndroid Build Coastguard Worker
7173*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_USAGE_ANGLE:
7174*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureUsageANGLE)
7175*8975f5c5SAndroid Build Coastguard Worker {
7176*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7177*8975f5c5SAndroid Build Coastguard Worker return false;
7178*8975f5c5SAndroid Build Coastguard Worker }
7179*8975f5c5SAndroid Build Coastguard Worker break;
7180*8975f5c5SAndroid Build Coastguard Worker
7181*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_ANISOTROPY_EXT:
7182*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
7183*8975f5c5SAndroid Build Coastguard Worker {
7184*8975f5c5SAndroid Build Coastguard Worker return false;
7185*8975f5c5SAndroid Build Coastguard Worker }
7186*8975f5c5SAndroid Build Coastguard Worker break;
7187*8975f5c5SAndroid Build Coastguard Worker
7188*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_IMMUTABLE_FORMAT:
7189*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorageEXT)
7190*8975f5c5SAndroid Build Coastguard Worker {
7191*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7192*8975f5c5SAndroid Build Coastguard Worker return false;
7193*8975f5c5SAndroid Build Coastguard Worker }
7194*8975f5c5SAndroid Build Coastguard Worker break;
7195*8975f5c5SAndroid Build Coastguard Worker
7196*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
7197*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_IMMUTABLE_LEVELS:
7198*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_R:
7199*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_G:
7200*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_B:
7201*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_A:
7202*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BASE_LEVEL:
7203*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LEVEL:
7204*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_LOD:
7205*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LOD:
7206*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
7207*8975f5c5SAndroid Build Coastguard Worker {
7208*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES30);
7209*8975f5c5SAndroid Build Coastguard Worker return false;
7210*8975f5c5SAndroid Build Coastguard Worker }
7211*8975f5c5SAndroid Build Coastguard Worker break;
7212*8975f5c5SAndroid Build Coastguard Worker
7213*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_MODE:
7214*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_FUNC:
7215*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 && !context->getExtensions().shadowSamplersEXT)
7216*8975f5c5SAndroid Build Coastguard Worker {
7217*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7218*8975f5c5SAndroid Build Coastguard Worker return false;
7219*8975f5c5SAndroid Build Coastguard Worker }
7220*8975f5c5SAndroid Build Coastguard Worker break;
7221*8975f5c5SAndroid Build Coastguard Worker
7222*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SRGB_DECODE_EXT:
7223*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureSRGBDecodeEXT)
7224*8975f5c5SAndroid Build Coastguard Worker {
7225*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7226*8975f5c5SAndroid Build Coastguard Worker return false;
7227*8975f5c5SAndroid Build Coastguard Worker }
7228*8975f5c5SAndroid Build Coastguard Worker break;
7229*8975f5c5SAndroid Build Coastguard Worker
7230*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_TEXTURE_MODE:
7231*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_1 &&
7232*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().stencilTexturingANGLE)
7233*8975f5c5SAndroid Build Coastguard Worker {
7234*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7235*8975f5c5SAndroid Build Coastguard Worker return false;
7236*8975f5c5SAndroid Build Coastguard Worker }
7237*8975f5c5SAndroid Build Coastguard Worker break;
7238*8975f5c5SAndroid Build Coastguard Worker
7239*8975f5c5SAndroid Build Coastguard Worker case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
7240*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_1)
7241*8975f5c5SAndroid Build Coastguard Worker {
7242*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
7243*8975f5c5SAndroid Build Coastguard Worker return false;
7244*8975f5c5SAndroid Build Coastguard Worker }
7245*8975f5c5SAndroid Build Coastguard Worker break;
7246*8975f5c5SAndroid Build Coastguard Worker
7247*8975f5c5SAndroid Build Coastguard Worker case GL_GENERATE_MIPMAP:
7248*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CROP_RECT_OES:
7249*8975f5c5SAndroid Build Coastguard Worker // TODO([email protected]): Restrict to GL_OES_draw_texture
7250*8975f5c5SAndroid Build Coastguard Worker // after GL_OES_draw_texture functionality implemented
7251*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() > 1)
7252*8975f5c5SAndroid Build Coastguard Worker {
7253*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
7254*8975f5c5SAndroid Build Coastguard Worker return false;
7255*8975f5c5SAndroid Build Coastguard Worker }
7256*8975f5c5SAndroid Build Coastguard Worker break;
7257*8975f5c5SAndroid Build Coastguard Worker
7258*8975f5c5SAndroid Build Coastguard Worker case GL_MEMORY_SIZE_ANGLE:
7259*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().memorySizeANGLE)
7260*8975f5c5SAndroid Build Coastguard Worker {
7261*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7262*8975f5c5SAndroid Build Coastguard Worker return false;
7263*8975f5c5SAndroid Build Coastguard Worker }
7264*8975f5c5SAndroid Build Coastguard Worker break;
7265*8975f5c5SAndroid Build Coastguard Worker
7266*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BORDER_COLOR:
7267*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureBorderClampAny() &&
7268*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
7269*8975f5c5SAndroid Build Coastguard Worker {
7270*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7271*8975f5c5SAndroid Build Coastguard Worker return false;
7272*8975f5c5SAndroid Build Coastguard Worker }
7273*8975f5c5SAndroid Build Coastguard Worker break;
7274*8975f5c5SAndroid Build Coastguard Worker
7275*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_NATIVE_ID_ANGLE:
7276*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureExternalUpdateANGLE)
7277*8975f5c5SAndroid Build Coastguard Worker {
7278*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7279*8975f5c5SAndroid Build Coastguard Worker return false;
7280*8975f5c5SAndroid Build Coastguard Worker }
7281*8975f5c5SAndroid Build Coastguard Worker break;
7282*8975f5c5SAndroid Build Coastguard Worker
7283*8975f5c5SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
7284*8975f5c5SAndroid Build Coastguard Worker case GL_IMPLEMENTATION_COLOR_READ_TYPE:
7285*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().getImageANGLE)
7286*8975f5c5SAndroid Build Coastguard Worker {
7287*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGetImageExtensionNotEnabled);
7288*8975f5c5SAndroid Build Coastguard Worker return false;
7289*8975f5c5SAndroid Build Coastguard Worker }
7290*8975f5c5SAndroid Build Coastguard Worker break;
7291*8975f5c5SAndroid Build Coastguard Worker
7292*8975f5c5SAndroid Build Coastguard Worker case GL_RESOURCE_INITIALIZED_ANGLE:
7293*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().robustResourceInitializationANGLE)
7294*8975f5c5SAndroid Build Coastguard Worker {
7295*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
7296*8975f5c5SAndroid Build Coastguard Worker kRobustResourceInitializationExtensionRequired);
7297*8975f5c5SAndroid Build Coastguard Worker return false;
7298*8975f5c5SAndroid Build Coastguard Worker }
7299*8975f5c5SAndroid Build Coastguard Worker break;
7300*8975f5c5SAndroid Build Coastguard Worker
7301*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_PROTECTED_EXT:
7302*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().protectedTexturesEXT)
7303*8975f5c5SAndroid Build Coastguard Worker {
7304*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProtectedTexturesExtensionRequired);
7305*8975f5c5SAndroid Build Coastguard Worker return false;
7306*8975f5c5SAndroid Build Coastguard Worker }
7307*8975f5c5SAndroid Build Coastguard Worker break;
7308*8975f5c5SAndroid Build Coastguard Worker
7309*8975f5c5SAndroid Build Coastguard Worker case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
7310*8975f5c5SAndroid Build Coastguard Worker break;
7311*8975f5c5SAndroid Build Coastguard Worker
7312*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM:
7313*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureFoveatedQCOM)
7314*8975f5c5SAndroid Build Coastguard Worker {
7315*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
7316*8975f5c5SAndroid Build Coastguard Worker return false;
7317*8975f5c5SAndroid Build Coastguard Worker }
7318*8975f5c5SAndroid Build Coastguard Worker break;
7319*8975f5c5SAndroid Build Coastguard Worker
7320*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM:
7321*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureFoveatedQCOM)
7322*8975f5c5SAndroid Build Coastguard Worker {
7323*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
7324*8975f5c5SAndroid Build Coastguard Worker return false;
7325*8975f5c5SAndroid Build Coastguard Worker }
7326*8975f5c5SAndroid Build Coastguard Worker break;
7327*8975f5c5SAndroid Build Coastguard Worker
7328*8975f5c5SAndroid Build Coastguard Worker case GL_SURFACE_COMPRESSION_EXT:
7329*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureStorageCompressionEXT)
7330*8975f5c5SAndroid Build Coastguard Worker {
7331*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
7332*8975f5c5SAndroid Build Coastguard Worker kTextureStorageCompressionExtensionRequired);
7333*8975f5c5SAndroid Build Coastguard Worker return false;
7334*8975f5c5SAndroid Build Coastguard Worker }
7335*8975f5c5SAndroid Build Coastguard Worker break;
7336*8975f5c5SAndroid Build Coastguard Worker
7337*8975f5c5SAndroid Build Coastguard Worker default:
7338*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7339*8975f5c5SAndroid Build Coastguard Worker return false;
7340*8975f5c5SAndroid Build Coastguard Worker }
7341*8975f5c5SAndroid Build Coastguard Worker
7342*8975f5c5SAndroid Build Coastguard Worker if (length)
7343*8975f5c5SAndroid Build Coastguard Worker {
7344*8975f5c5SAndroid Build Coastguard Worker *length = GetTexParameterCount(pname);
7345*8975f5c5SAndroid Build Coastguard Worker }
7346*8975f5c5SAndroid Build Coastguard Worker return true;
7347*8975f5c5SAndroid Build Coastguard Worker }
7348*8975f5c5SAndroid Build Coastguard Worker
ValidateGetVertexAttribBase(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei * length,bool pointer,bool pureIntegerEntryPoint)7349*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribBase(const Context *context,
7350*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
7351*8975f5c5SAndroid Build Coastguard Worker GLuint index,
7352*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
7353*8975f5c5SAndroid Build Coastguard Worker GLsizei *length,
7354*8975f5c5SAndroid Build Coastguard Worker bool pointer,
7355*8975f5c5SAndroid Build Coastguard Worker bool pureIntegerEntryPoint)
7356*8975f5c5SAndroid Build Coastguard Worker {
7357*8975f5c5SAndroid Build Coastguard Worker if (length)
7358*8975f5c5SAndroid Build Coastguard Worker {
7359*8975f5c5SAndroid Build Coastguard Worker *length = 0;
7360*8975f5c5SAndroid Build Coastguard Worker }
7361*8975f5c5SAndroid Build Coastguard Worker
7362*8975f5c5SAndroid Build Coastguard Worker if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
7363*8975f5c5SAndroid Build Coastguard Worker {
7364*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
7365*8975f5c5SAndroid Build Coastguard Worker return false;
7366*8975f5c5SAndroid Build Coastguard Worker }
7367*8975f5c5SAndroid Build Coastguard Worker
7368*8975f5c5SAndroid Build Coastguard Worker if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
7369*8975f5c5SAndroid Build Coastguard Worker {
7370*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
7371*8975f5c5SAndroid Build Coastguard Worker return false;
7372*8975f5c5SAndroid Build Coastguard Worker }
7373*8975f5c5SAndroid Build Coastguard Worker
7374*8975f5c5SAndroid Build Coastguard Worker if (pointer)
7375*8975f5c5SAndroid Build Coastguard Worker {
7376*8975f5c5SAndroid Build Coastguard Worker if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
7377*8975f5c5SAndroid Build Coastguard Worker {
7378*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7379*8975f5c5SAndroid Build Coastguard Worker return false;
7380*8975f5c5SAndroid Build Coastguard Worker }
7381*8975f5c5SAndroid Build Coastguard Worker }
7382*8975f5c5SAndroid Build Coastguard Worker else
7383*8975f5c5SAndroid Build Coastguard Worker {
7384*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7385*8975f5c5SAndroid Build Coastguard Worker {
7386*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
7387*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_SIZE:
7388*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
7389*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_TYPE:
7390*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
7391*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
7392*8975f5c5SAndroid Build Coastguard Worker case GL_CURRENT_VERTEX_ATTRIB:
7393*8975f5c5SAndroid Build Coastguard Worker break;
7394*8975f5c5SAndroid Build Coastguard Worker
7395*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
7396*8975f5c5SAndroid Build Coastguard Worker static_assert(
7397*8975f5c5SAndroid Build Coastguard Worker GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
7398*8975f5c5SAndroid Build Coastguard Worker "ANGLE extension enums not equal to GL enums.");
7399*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 &&
7400*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().instancedArraysAny())
7401*8975f5c5SAndroid Build Coastguard Worker {
7402*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7403*8975f5c5SAndroid Build Coastguard Worker return false;
7404*8975f5c5SAndroid Build Coastguard Worker }
7405*8975f5c5SAndroid Build Coastguard Worker break;
7406*8975f5c5SAndroid Build Coastguard Worker
7407*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
7408*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
7409*8975f5c5SAndroid Build Coastguard Worker {
7410*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7411*8975f5c5SAndroid Build Coastguard Worker return false;
7412*8975f5c5SAndroid Build Coastguard Worker }
7413*8975f5c5SAndroid Build Coastguard Worker break;
7414*8975f5c5SAndroid Build Coastguard Worker
7415*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_BINDING:
7416*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
7417*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_1)
7418*8975f5c5SAndroid Build Coastguard Worker {
7419*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
7420*8975f5c5SAndroid Build Coastguard Worker return false;
7421*8975f5c5SAndroid Build Coastguard Worker }
7422*8975f5c5SAndroid Build Coastguard Worker break;
7423*8975f5c5SAndroid Build Coastguard Worker
7424*8975f5c5SAndroid Build Coastguard Worker default:
7425*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7426*8975f5c5SAndroid Build Coastguard Worker return false;
7427*8975f5c5SAndroid Build Coastguard Worker }
7428*8975f5c5SAndroid Build Coastguard Worker }
7429*8975f5c5SAndroid Build Coastguard Worker
7430*8975f5c5SAndroid Build Coastguard Worker if (length)
7431*8975f5c5SAndroid Build Coastguard Worker {
7432*8975f5c5SAndroid Build Coastguard Worker if (pname == GL_CURRENT_VERTEX_ATTRIB)
7433*8975f5c5SAndroid Build Coastguard Worker {
7434*8975f5c5SAndroid Build Coastguard Worker *length = 4;
7435*8975f5c5SAndroid Build Coastguard Worker }
7436*8975f5c5SAndroid Build Coastguard Worker else
7437*8975f5c5SAndroid Build Coastguard Worker {
7438*8975f5c5SAndroid Build Coastguard Worker *length = 1;
7439*8975f5c5SAndroid Build Coastguard Worker }
7440*8975f5c5SAndroid Build Coastguard Worker }
7441*8975f5c5SAndroid Build Coastguard Worker
7442*8975f5c5SAndroid Build Coastguard Worker return true;
7443*8975f5c5SAndroid Build Coastguard Worker }
7444*8975f5c5SAndroid Build Coastguard Worker
ValidatePixelPack(const Context * context,angle::EntryPoint entryPoint,GLenum format,GLenum type,GLint x,GLint y,GLsizei width,GLsizei height,GLsizei bufSize,GLsizei * length,const void * pixels)7445*8975f5c5SAndroid Build Coastguard Worker bool ValidatePixelPack(const Context *context,
7446*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
7447*8975f5c5SAndroid Build Coastguard Worker GLenum format,
7448*8975f5c5SAndroid Build Coastguard Worker GLenum type,
7449*8975f5c5SAndroid Build Coastguard Worker GLint x,
7450*8975f5c5SAndroid Build Coastguard Worker GLint y,
7451*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
7452*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
7453*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
7454*8975f5c5SAndroid Build Coastguard Worker GLsizei *length,
7455*8975f5c5SAndroid Build Coastguard Worker const void *pixels)
7456*8975f5c5SAndroid Build Coastguard Worker {
7457*8975f5c5SAndroid Build Coastguard Worker // Check for pixel pack buffer related API errors
7458*8975f5c5SAndroid Build Coastguard Worker Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack);
7459*8975f5c5SAndroid Build Coastguard Worker if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
7460*8975f5c5SAndroid Build Coastguard Worker {
7461*8975f5c5SAndroid Build Coastguard Worker // ...the buffer object's data store is currently mapped.
7462*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferMapped);
7463*8975f5c5SAndroid Build Coastguard Worker return false;
7464*8975f5c5SAndroid Build Coastguard Worker }
7465*8975f5c5SAndroid Build Coastguard Worker if (pixelPackBuffer != nullptr &&
7466*8975f5c5SAndroid Build Coastguard Worker pixelPackBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
7467*8975f5c5SAndroid Build Coastguard Worker {
7468*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
7469*8975f5c5SAndroid Build Coastguard Worker return false;
7470*8975f5c5SAndroid Build Coastguard Worker }
7471*8975f5c5SAndroid Build Coastguard Worker
7472*8975f5c5SAndroid Build Coastguard Worker // .. the data would be packed to the buffer object such that the memory writes required
7473*8975f5c5SAndroid Build Coastguard Worker // would exceed the data store size.
7474*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
7475*8975f5c5SAndroid Build Coastguard Worker const Extents size(width, height, 1);
7476*8975f5c5SAndroid Build Coastguard Worker const auto &pack = context->getState().getPackState();
7477*8975f5c5SAndroid Build Coastguard Worker
7478*8975f5c5SAndroid Build Coastguard Worker GLuint endByte = 0;
7479*8975f5c5SAndroid Build Coastguard Worker if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
7480*8975f5c5SAndroid Build Coastguard Worker {
7481*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7482*8975f5c5SAndroid Build Coastguard Worker return false;
7483*8975f5c5SAndroid Build Coastguard Worker }
7484*8975f5c5SAndroid Build Coastguard Worker
7485*8975f5c5SAndroid Build Coastguard Worker if (bufSize >= 0)
7486*8975f5c5SAndroid Build Coastguard Worker {
7487*8975f5c5SAndroid Build Coastguard Worker if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
7488*8975f5c5SAndroid Build Coastguard Worker {
7489*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
7490*8975f5c5SAndroid Build Coastguard Worker return false;
7491*8975f5c5SAndroid Build Coastguard Worker }
7492*8975f5c5SAndroid Build Coastguard Worker }
7493*8975f5c5SAndroid Build Coastguard Worker
7494*8975f5c5SAndroid Build Coastguard Worker if (pixelPackBuffer != nullptr)
7495*8975f5c5SAndroid Build Coastguard Worker {
7496*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<size_t> checkedEndByte(endByte);
7497*8975f5c5SAndroid Build Coastguard Worker CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
7498*8975f5c5SAndroid Build Coastguard Worker checkedEndByte += checkedOffset;
7499*8975f5c5SAndroid Build Coastguard Worker
7500*8975f5c5SAndroid Build Coastguard Worker if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
7501*8975f5c5SAndroid Build Coastguard Worker {
7502*8975f5c5SAndroid Build Coastguard Worker // Overflow past the end of the buffer
7503*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kParamOverflow);
7504*8975f5c5SAndroid Build Coastguard Worker return false;
7505*8975f5c5SAndroid Build Coastguard Worker }
7506*8975f5c5SAndroid Build Coastguard Worker }
7507*8975f5c5SAndroid Build Coastguard Worker
7508*8975f5c5SAndroid Build Coastguard Worker if (pixelPackBuffer == nullptr && length != nullptr)
7509*8975f5c5SAndroid Build Coastguard Worker {
7510*8975f5c5SAndroid Build Coastguard Worker if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
7511*8975f5c5SAndroid Build Coastguard Worker {
7512*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7513*8975f5c5SAndroid Build Coastguard Worker return false;
7514*8975f5c5SAndroid Build Coastguard Worker }
7515*8975f5c5SAndroid Build Coastguard Worker
7516*8975f5c5SAndroid Build Coastguard Worker *length = static_cast<GLsizei>(endByte);
7517*8975f5c5SAndroid Build Coastguard Worker }
7518*8975f5c5SAndroid Build Coastguard Worker
7519*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL())
7520*8975f5c5SAndroid Build Coastguard Worker {
7521*8975f5c5SAndroid Build Coastguard Worker // WebGL 2.0 disallows the scenario:
7522*8975f5c5SAndroid Build Coastguard Worker // GL_PACK_SKIP_PIXELS + width > DataStoreWidth
7523*8975f5c5SAndroid Build Coastguard Worker // where:
7524*8975f5c5SAndroid Build Coastguard Worker // DataStoreWidth = (GL_PACK_ROW_LENGTH ? GL_PACK_ROW_LENGTH : width)
7525*8975f5c5SAndroid Build Coastguard Worker // Since these two pack parameters can only be set to non-zero values
7526*8975f5c5SAndroid Build Coastguard Worker // on WebGL 2.0 contexts, verify them for all WebGL contexts.
7527*8975f5c5SAndroid Build Coastguard Worker GLint dataStoreWidth = pack.rowLength ? pack.rowLength : width;
7528*8975f5c5SAndroid Build Coastguard Worker if (pack.skipPixels + width > dataStoreWidth)
7529*8975f5c5SAndroid Build Coastguard Worker {
7530*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidPackParametersForWebGL);
7531*8975f5c5SAndroid Build Coastguard Worker return false;
7532*8975f5c5SAndroid Build Coastguard Worker }
7533*8975f5c5SAndroid Build Coastguard Worker }
7534*8975f5c5SAndroid Build Coastguard Worker
7535*8975f5c5SAndroid Build Coastguard Worker return true;
7536*8975f5c5SAndroid Build Coastguard Worker }
7537*8975f5c5SAndroid Build Coastguard Worker
ValidateReadPixelsBase(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLsizei * length,GLsizei * columns,GLsizei * rows,const void * pixels)7538*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadPixelsBase(const Context *context,
7539*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
7540*8975f5c5SAndroid Build Coastguard Worker GLint x,
7541*8975f5c5SAndroid Build Coastguard Worker GLint y,
7542*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
7543*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
7544*8975f5c5SAndroid Build Coastguard Worker GLenum format,
7545*8975f5c5SAndroid Build Coastguard Worker GLenum type,
7546*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
7547*8975f5c5SAndroid Build Coastguard Worker GLsizei *length,
7548*8975f5c5SAndroid Build Coastguard Worker GLsizei *columns,
7549*8975f5c5SAndroid Build Coastguard Worker GLsizei *rows,
7550*8975f5c5SAndroid Build Coastguard Worker const void *pixels)
7551*8975f5c5SAndroid Build Coastguard Worker {
7552*8975f5c5SAndroid Build Coastguard Worker if (length != nullptr)
7553*8975f5c5SAndroid Build Coastguard Worker {
7554*8975f5c5SAndroid Build Coastguard Worker *length = 0;
7555*8975f5c5SAndroid Build Coastguard Worker }
7556*8975f5c5SAndroid Build Coastguard Worker if (rows != nullptr)
7557*8975f5c5SAndroid Build Coastguard Worker {
7558*8975f5c5SAndroid Build Coastguard Worker *rows = 0;
7559*8975f5c5SAndroid Build Coastguard Worker }
7560*8975f5c5SAndroid Build Coastguard Worker if (columns != nullptr)
7561*8975f5c5SAndroid Build Coastguard Worker {
7562*8975f5c5SAndroid Build Coastguard Worker *columns = 0;
7563*8975f5c5SAndroid Build Coastguard Worker }
7564*8975f5c5SAndroid Build Coastguard Worker
7565*8975f5c5SAndroid Build Coastguard Worker if (width < 0 || height < 0)
7566*8975f5c5SAndroid Build Coastguard Worker {
7567*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
7568*8975f5c5SAndroid Build Coastguard Worker return false;
7569*8975f5c5SAndroid Build Coastguard Worker }
7570*8975f5c5SAndroid Build Coastguard Worker
7571*8975f5c5SAndroid Build Coastguard Worker Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
7572*8975f5c5SAndroid Build Coastguard Worker ASSERT(readFramebuffer);
7573*8975f5c5SAndroid Build Coastguard Worker
7574*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
7575*8975f5c5SAndroid Build Coastguard Worker {
7576*8975f5c5SAndroid Build Coastguard Worker return false;
7577*8975f5c5SAndroid Build Coastguard Worker }
7578*8975f5c5SAndroid Build Coastguard Worker
7579*8975f5c5SAndroid Build Coastguard Worker // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be
7580*8975f5c5SAndroid Build Coastguard Worker // resolved before reading.
7581*8975f5c5SAndroid Build Coastguard Worker if (!readFramebuffer->isDefault() &&
7582*8975f5c5SAndroid Build Coastguard Worker !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true))
7583*8975f5c5SAndroid Build Coastguard Worker {
7584*8975f5c5SAndroid Build Coastguard Worker return false;
7585*8975f5c5SAndroid Build Coastguard Worker }
7586*8975f5c5SAndroid Build Coastguard Worker
7587*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->getReadBufferState() == GL_NONE)
7588*8975f5c5SAndroid Build Coastguard Worker {
7589*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNone);
7590*8975f5c5SAndroid Build Coastguard Worker return false;
7591*8975f5c5SAndroid Build Coastguard Worker }
7592*8975f5c5SAndroid Build Coastguard Worker
7593*8975f5c5SAndroid Build Coastguard Worker const FramebufferAttachment *readBuffer = nullptr;
7594*8975f5c5SAndroid Build Coastguard Worker switch (format)
7595*8975f5c5SAndroid Build Coastguard Worker {
7596*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
7597*8975f5c5SAndroid Build Coastguard Worker readBuffer = readFramebuffer->getDepthAttachment();
7598*8975f5c5SAndroid Build Coastguard Worker break;
7599*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_INDEX_OES:
7600*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_OES:
7601*8975f5c5SAndroid Build Coastguard Worker readBuffer = readFramebuffer->getStencilOrDepthStencilAttachment();
7602*8975f5c5SAndroid Build Coastguard Worker break;
7603*8975f5c5SAndroid Build Coastguard Worker default:
7604*8975f5c5SAndroid Build Coastguard Worker readBuffer = readFramebuffer->getReadColorAttachment();
7605*8975f5c5SAndroid Build Coastguard Worker break;
7606*8975f5c5SAndroid Build Coastguard Worker }
7607*8975f5c5SAndroid Build Coastguard Worker
7608*8975f5c5SAndroid Build Coastguard Worker // OVR_multiview2, Revision 1:
7609*8975f5c5SAndroid Build Coastguard Worker // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if
7610*8975f5c5SAndroid Build Coastguard Worker // the number of views in the current read framebuffer is more than one.
7611*8975f5c5SAndroid Build Coastguard Worker if (readFramebuffer->readDisallowedByMultiview())
7612*8975f5c5SAndroid Build Coastguard Worker {
7613*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
7614*8975f5c5SAndroid Build Coastguard Worker return false;
7615*8975f5c5SAndroid Build Coastguard Worker }
7616*8975f5c5SAndroid Build Coastguard Worker
7617*8975f5c5SAndroid Build Coastguard Worker if (context->isWebGL())
7618*8975f5c5SAndroid Build Coastguard Worker {
7619*8975f5c5SAndroid Build Coastguard Worker // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
7620*8975f5c5SAndroid Build Coastguard Worker // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
7621*8975f5c5SAndroid Build Coastguard Worker // and type before validating the combination of format and type. However, the
7622*8975f5c5SAndroid Build Coastguard Worker // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
7623*8975f5c5SAndroid Build Coastguard Worker // verifies that GL_INVALID_OPERATION is generated.
7624*8975f5c5SAndroid Build Coastguard Worker // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
7625*8975f5c5SAndroid Build Coastguard Worker // dEQP/WebGL.
7626*8975f5c5SAndroid Build Coastguard Worker if (!ValidReadPixelsFormatEnum(context, format))
7627*8975f5c5SAndroid Build Coastguard Worker {
7628*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
7629*8975f5c5SAndroid Build Coastguard Worker return false;
7630*8975f5c5SAndroid Build Coastguard Worker }
7631*8975f5c5SAndroid Build Coastguard Worker
7632*8975f5c5SAndroid Build Coastguard Worker if (!ValidReadPixelsTypeEnum(context, type))
7633*8975f5c5SAndroid Build Coastguard Worker {
7634*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
7635*8975f5c5SAndroid Build Coastguard Worker return false;
7636*8975f5c5SAndroid Build Coastguard Worker }
7637*8975f5c5SAndroid Build Coastguard Worker }
7638*8975f5c5SAndroid Build Coastguard Worker
7639*8975f5c5SAndroid Build Coastguard Worker // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
7640*8975f5c5SAndroid Build Coastguard Worker // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
7641*8975f5c5SAndroid Build Coastguard Worker // attachment and WebGL defines it to be an error. We do the check unconditionally as the
7642*8975f5c5SAndroid Build Coastguard Worker // situation is an application error that would lead to a crash in ANGLE.
7643*8975f5c5SAndroid Build Coastguard Worker if (readBuffer == nullptr)
7644*8975f5c5SAndroid Build Coastguard Worker {
7645*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingReadAttachment);
7646*8975f5c5SAndroid Build Coastguard Worker return false;
7647*8975f5c5SAndroid Build Coastguard Worker }
7648*8975f5c5SAndroid Build Coastguard Worker
7649*8975f5c5SAndroid Build Coastguard Worker GLenum currentFormat = GL_NONE;
7650*8975f5c5SAndroid Build Coastguard Worker GLenum currentType = GL_NONE;
7651*8975f5c5SAndroid Build Coastguard Worker
7652*8975f5c5SAndroid Build Coastguard Worker switch (format)
7653*8975f5c5SAndroid Build Coastguard Worker {
7654*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
7655*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_INDEX_OES:
7656*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_OES:
7657*8975f5c5SAndroid Build Coastguard Worker // Only rely on ValidReadPixelsFormatType for depth/stencil formats
7658*8975f5c5SAndroid Build Coastguard Worker break;
7659*8975f5c5SAndroid Build Coastguard Worker default:
7660*8975f5c5SAndroid Build Coastguard Worker currentFormat = readFramebuffer->getImplementationColorReadFormat(context);
7661*8975f5c5SAndroid Build Coastguard Worker currentType = readFramebuffer->getImplementationColorReadType(context);
7662*8975f5c5SAndroid Build Coastguard Worker break;
7663*8975f5c5SAndroid Build Coastguard Worker }
7664*8975f5c5SAndroid Build Coastguard Worker
7665*8975f5c5SAndroid Build Coastguard Worker bool validFormatTypeCombination =
7666*8975f5c5SAndroid Build Coastguard Worker ValidReadPixelsFormatType(context, readBuffer->getFormat().info, format, type);
7667*8975f5c5SAndroid Build Coastguard Worker
7668*8975f5c5SAndroid Build Coastguard Worker if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
7669*8975f5c5SAndroid Build Coastguard Worker {
7670*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
7671*8975f5c5SAndroid Build Coastguard Worker return false;
7672*8975f5c5SAndroid Build Coastguard Worker }
7673*8975f5c5SAndroid Build Coastguard Worker
7674*8975f5c5SAndroid Build Coastguard Worker if (!ValidatePixelPack(context, entryPoint, format, type, x, y, width, height, bufSize, length,
7675*8975f5c5SAndroid Build Coastguard Worker pixels))
7676*8975f5c5SAndroid Build Coastguard Worker {
7677*8975f5c5SAndroid Build Coastguard Worker return false;
7678*8975f5c5SAndroid Build Coastguard Worker }
7679*8975f5c5SAndroid Build Coastguard Worker
7680*8975f5c5SAndroid Build Coastguard Worker auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
7681*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<int> clippedExtent(length);
7682*8975f5c5SAndroid Build Coastguard Worker if (start < 0)
7683*8975f5c5SAndroid Build Coastguard Worker {
7684*8975f5c5SAndroid Build Coastguard Worker // "subtract" the area that is less than 0
7685*8975f5c5SAndroid Build Coastguard Worker clippedExtent += start;
7686*8975f5c5SAndroid Build Coastguard Worker }
7687*8975f5c5SAndroid Build Coastguard Worker
7688*8975f5c5SAndroid Build Coastguard Worker angle::CheckedNumeric<int> readExtent = start;
7689*8975f5c5SAndroid Build Coastguard Worker readExtent += length;
7690*8975f5c5SAndroid Build Coastguard Worker if (!readExtent.IsValid())
7691*8975f5c5SAndroid Build Coastguard Worker {
7692*8975f5c5SAndroid Build Coastguard Worker return false;
7693*8975f5c5SAndroid Build Coastguard Worker }
7694*8975f5c5SAndroid Build Coastguard Worker
7695*8975f5c5SAndroid Build Coastguard Worker if (readExtent.ValueOrDie() > bufferSize)
7696*8975f5c5SAndroid Build Coastguard Worker {
7697*8975f5c5SAndroid Build Coastguard Worker // Subtract the region to the right of the read buffer
7698*8975f5c5SAndroid Build Coastguard Worker clippedExtent -= (readExtent - bufferSize);
7699*8975f5c5SAndroid Build Coastguard Worker }
7700*8975f5c5SAndroid Build Coastguard Worker
7701*8975f5c5SAndroid Build Coastguard Worker if (!clippedExtent.IsValid())
7702*8975f5c5SAndroid Build Coastguard Worker {
7703*8975f5c5SAndroid Build Coastguard Worker return false;
7704*8975f5c5SAndroid Build Coastguard Worker }
7705*8975f5c5SAndroid Build Coastguard Worker
7706*8975f5c5SAndroid Build Coastguard Worker *outExtent = std::max<int>(clippedExtent.ValueOrDie(), 0);
7707*8975f5c5SAndroid Build Coastguard Worker return true;
7708*8975f5c5SAndroid Build Coastguard Worker };
7709*8975f5c5SAndroid Build Coastguard Worker
7710*8975f5c5SAndroid Build Coastguard Worker GLsizei writtenColumns = 0;
7711*8975f5c5SAndroid Build Coastguard Worker if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
7712*8975f5c5SAndroid Build Coastguard Worker {
7713*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7714*8975f5c5SAndroid Build Coastguard Worker return false;
7715*8975f5c5SAndroid Build Coastguard Worker }
7716*8975f5c5SAndroid Build Coastguard Worker
7717*8975f5c5SAndroid Build Coastguard Worker GLsizei writtenRows = 0;
7718*8975f5c5SAndroid Build Coastguard Worker if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
7719*8975f5c5SAndroid Build Coastguard Worker {
7720*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7721*8975f5c5SAndroid Build Coastguard Worker return false;
7722*8975f5c5SAndroid Build Coastguard Worker }
7723*8975f5c5SAndroid Build Coastguard Worker
7724*8975f5c5SAndroid Build Coastguard Worker if (columns != nullptr)
7725*8975f5c5SAndroid Build Coastguard Worker {
7726*8975f5c5SAndroid Build Coastguard Worker *columns = writtenColumns;
7727*8975f5c5SAndroid Build Coastguard Worker }
7728*8975f5c5SAndroid Build Coastguard Worker
7729*8975f5c5SAndroid Build Coastguard Worker if (rows != nullptr)
7730*8975f5c5SAndroid Build Coastguard Worker {
7731*8975f5c5SAndroid Build Coastguard Worker *rows = writtenRows;
7732*8975f5c5SAndroid Build Coastguard Worker }
7733*8975f5c5SAndroid Build Coastguard Worker
7734*8975f5c5SAndroid Build Coastguard Worker return true;
7735*8975f5c5SAndroid Build Coastguard Worker }
7736*8975f5c5SAndroid Build Coastguard Worker
7737*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTexParameterBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,bool vectorParams,const ParamType * params)7738*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterBase(const Context *context,
7739*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
7740*8975f5c5SAndroid Build Coastguard Worker TextureType target,
7741*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
7742*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
7743*8975f5c5SAndroid Build Coastguard Worker bool vectorParams,
7744*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
7745*8975f5c5SAndroid Build Coastguard Worker {
7746*8975f5c5SAndroid Build Coastguard Worker if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) ||
7747*8975f5c5SAndroid Build Coastguard Worker target == TextureType::Buffer)
7748*8975f5c5SAndroid Build Coastguard Worker {
7749*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
7750*8975f5c5SAndroid Build Coastguard Worker return false;
7751*8975f5c5SAndroid Build Coastguard Worker }
7752*8975f5c5SAndroid Build Coastguard Worker
7753*8975f5c5SAndroid Build Coastguard Worker if (context->getTextureByType(target) == nullptr)
7754*8975f5c5SAndroid Build Coastguard Worker {
7755*8975f5c5SAndroid Build Coastguard Worker // Should only be possible for external textures
7756*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureNotBound);
7757*8975f5c5SAndroid Build Coastguard Worker return false;
7758*8975f5c5SAndroid Build Coastguard Worker }
7759*8975f5c5SAndroid Build Coastguard Worker
7760*8975f5c5SAndroid Build Coastguard Worker const GLsizei minBufSize = GetTexParameterCount(pname);
7761*8975f5c5SAndroid Build Coastguard Worker if (bufSize >= 0 && bufSize < minBufSize)
7762*8975f5c5SAndroid Build Coastguard Worker {
7763*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
7764*8975f5c5SAndroid Build Coastguard Worker return false;
7765*8975f5c5SAndroid Build Coastguard Worker }
7766*8975f5c5SAndroid Build Coastguard Worker
7767*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
7768*8975f5c5SAndroid Build Coastguard Worker {
7769*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7770*8975f5c5SAndroid Build Coastguard Worker return false;
7771*8975f5c5SAndroid Build Coastguard Worker }
7772*8975f5c5SAndroid Build Coastguard Worker
7773*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7774*8975f5c5SAndroid Build Coastguard Worker {
7775*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
7776*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_R:
7777*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_G:
7778*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_B:
7779*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_A:
7780*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BASE_LEVEL:
7781*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LEVEL:
7782*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_MODE:
7783*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_FUNC:
7784*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_LOD:
7785*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LOD:
7786*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3 &&
7787*8975f5c5SAndroid Build Coastguard Worker !(pname == GL_TEXTURE_WRAP_R && context->getExtensions().texture3DOES))
7788*8975f5c5SAndroid Build Coastguard Worker {
7789*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES3Required);
7790*8975f5c5SAndroid Build Coastguard Worker return false;
7791*8975f5c5SAndroid Build Coastguard Worker }
7792*8975f5c5SAndroid Build Coastguard Worker if (target == TextureType::VideoImage && !context->getExtensions().videoTextureWEBGL)
7793*8975f5c5SAndroid Build Coastguard Worker {
7794*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7795*8975f5c5SAndroid Build Coastguard Worker }
7796*8975f5c5SAndroid Build Coastguard Worker break;
7797*8975f5c5SAndroid Build Coastguard Worker
7798*8975f5c5SAndroid Build Coastguard Worker case GL_GENERATE_MIPMAP:
7799*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CROP_RECT_OES:
7800*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() > 1)
7801*8975f5c5SAndroid Build Coastguard Worker {
7802*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
7803*8975f5c5SAndroid Build Coastguard Worker return false;
7804*8975f5c5SAndroid Build Coastguard Worker }
7805*8975f5c5SAndroid Build Coastguard Worker break;
7806*8975f5c5SAndroid Build Coastguard Worker
7807*8975f5c5SAndroid Build Coastguard Worker default:
7808*8975f5c5SAndroid Build Coastguard Worker break;
7809*8975f5c5SAndroid Build Coastguard Worker }
7810*8975f5c5SAndroid Build Coastguard Worker
7811*8975f5c5SAndroid Build Coastguard Worker if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
7812*8975f5c5SAndroid Build Coastguard Worker {
7813*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7814*8975f5c5SAndroid Build Coastguard Worker {
7815*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_FILTER:
7816*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAG_FILTER:
7817*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_S:
7818*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_T:
7819*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
7820*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_LOD:
7821*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LOD:
7822*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_MODE:
7823*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_FUNC:
7824*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BORDER_COLOR:
7825*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
7826*8975f5c5SAndroid Build Coastguard Worker return false;
7827*8975f5c5SAndroid Build Coastguard Worker }
7828*8975f5c5SAndroid Build Coastguard Worker }
7829*8975f5c5SAndroid Build Coastguard Worker
7830*8975f5c5SAndroid Build Coastguard Worker switch (pname)
7831*8975f5c5SAndroid Build Coastguard Worker {
7832*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_S:
7833*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_T:
7834*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
7835*8975f5c5SAndroid Build Coastguard Worker {
7836*8975f5c5SAndroid Build Coastguard Worker bool restrictedWrapModes = ((target == TextureType::External &&
7837*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().EGLImageExternalWrapModesEXT) ||
7838*8975f5c5SAndroid Build Coastguard Worker target == TextureType::Rectangle);
7839*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureWrapModeValue(context, entryPoint, params, restrictedWrapModes))
7840*8975f5c5SAndroid Build Coastguard Worker {
7841*8975f5c5SAndroid Build Coastguard Worker return false;
7842*8975f5c5SAndroid Build Coastguard Worker }
7843*8975f5c5SAndroid Build Coastguard Worker }
7844*8975f5c5SAndroid Build Coastguard Worker break;
7845*8975f5c5SAndroid Build Coastguard Worker
7846*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_FILTER:
7847*8975f5c5SAndroid Build Coastguard Worker {
7848*8975f5c5SAndroid Build Coastguard Worker bool restrictedMinFilter =
7849*8975f5c5SAndroid Build Coastguard Worker target == TextureType::External || target == TextureType::Rectangle;
7850*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMinFilterValue(context, entryPoint, params, restrictedMinFilter))
7851*8975f5c5SAndroid Build Coastguard Worker {
7852*8975f5c5SAndroid Build Coastguard Worker return false;
7853*8975f5c5SAndroid Build Coastguard Worker }
7854*8975f5c5SAndroid Build Coastguard Worker }
7855*8975f5c5SAndroid Build Coastguard Worker break;
7856*8975f5c5SAndroid Build Coastguard Worker
7857*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAG_FILTER:
7858*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMagFilterValue(context, entryPoint, params))
7859*8975f5c5SAndroid Build Coastguard Worker {
7860*8975f5c5SAndroid Build Coastguard Worker return false;
7861*8975f5c5SAndroid Build Coastguard Worker }
7862*8975f5c5SAndroid Build Coastguard Worker break;
7863*8975f5c5SAndroid Build Coastguard Worker
7864*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_USAGE_ANGLE:
7865*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureUsageANGLE)
7866*8975f5c5SAndroid Build Coastguard Worker {
7867*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7868*8975f5c5SAndroid Build Coastguard Worker return false;
7869*8975f5c5SAndroid Build Coastguard Worker }
7870*8975f5c5SAndroid Build Coastguard Worker
7871*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
7872*8975f5c5SAndroid Build Coastguard Worker {
7873*8975f5c5SAndroid Build Coastguard Worker case GL_NONE:
7874*8975f5c5SAndroid Build Coastguard Worker case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
7875*8975f5c5SAndroid Build Coastguard Worker break;
7876*8975f5c5SAndroid Build Coastguard Worker
7877*8975f5c5SAndroid Build Coastguard Worker default:
7878*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7879*8975f5c5SAndroid Build Coastguard Worker return false;
7880*8975f5c5SAndroid Build Coastguard Worker }
7881*8975f5c5SAndroid Build Coastguard Worker break;
7882*8975f5c5SAndroid Build Coastguard Worker
7883*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_ANISOTROPY_EXT:
7884*8975f5c5SAndroid Build Coastguard Worker {
7885*8975f5c5SAndroid Build Coastguard Worker GLfloat paramValue = static_cast<GLfloat>(params[0]);
7886*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue))
7887*8975f5c5SAndroid Build Coastguard Worker {
7888*8975f5c5SAndroid Build Coastguard Worker return false;
7889*8975f5c5SAndroid Build Coastguard Worker }
7890*8975f5c5SAndroid Build Coastguard Worker ASSERT(static_cast<ParamType>(paramValue) == params[0]);
7891*8975f5c5SAndroid Build Coastguard Worker }
7892*8975f5c5SAndroid Build Coastguard Worker break;
7893*8975f5c5SAndroid Build Coastguard Worker
7894*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_LOD:
7895*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LOD:
7896*8975f5c5SAndroid Build Coastguard Worker // any value is permissible
7897*8975f5c5SAndroid Build Coastguard Worker break;
7898*8975f5c5SAndroid Build Coastguard Worker
7899*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_MODE:
7900*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureCompareModeValue(context, entryPoint, params))
7901*8975f5c5SAndroid Build Coastguard Worker {
7902*8975f5c5SAndroid Build Coastguard Worker return false;
7903*8975f5c5SAndroid Build Coastguard Worker }
7904*8975f5c5SAndroid Build Coastguard Worker break;
7905*8975f5c5SAndroid Build Coastguard Worker
7906*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_FUNC:
7907*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureCompareFuncValue(context, entryPoint, params))
7908*8975f5c5SAndroid Build Coastguard Worker {
7909*8975f5c5SAndroid Build Coastguard Worker return false;
7910*8975f5c5SAndroid Build Coastguard Worker }
7911*8975f5c5SAndroid Build Coastguard Worker break;
7912*8975f5c5SAndroid Build Coastguard Worker
7913*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_R:
7914*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_G:
7915*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_B:
7916*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SWIZZLE_A:
7917*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
7918*8975f5c5SAndroid Build Coastguard Worker {
7919*8975f5c5SAndroid Build Coastguard Worker case GL_RED:
7920*8975f5c5SAndroid Build Coastguard Worker case GL_GREEN:
7921*8975f5c5SAndroid Build Coastguard Worker case GL_BLUE:
7922*8975f5c5SAndroid Build Coastguard Worker case GL_ALPHA:
7923*8975f5c5SAndroid Build Coastguard Worker case GL_ZERO:
7924*8975f5c5SAndroid Build Coastguard Worker case GL_ONE:
7925*8975f5c5SAndroid Build Coastguard Worker break;
7926*8975f5c5SAndroid Build Coastguard Worker
7927*8975f5c5SAndroid Build Coastguard Worker default:
7928*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7929*8975f5c5SAndroid Build Coastguard Worker return false;
7930*8975f5c5SAndroid Build Coastguard Worker }
7931*8975f5c5SAndroid Build Coastguard Worker break;
7932*8975f5c5SAndroid Build Coastguard Worker
7933*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BASE_LEVEL:
7934*8975f5c5SAndroid Build Coastguard Worker if (ConvertToGLint(params[0]) < 0)
7935*8975f5c5SAndroid Build Coastguard Worker {
7936*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBaseLevelNegative);
7937*8975f5c5SAndroid Build Coastguard Worker return false;
7938*8975f5c5SAndroid Build Coastguard Worker }
7939*8975f5c5SAndroid Build Coastguard Worker if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
7940*8975f5c5SAndroid Build Coastguard Worker {
7941*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelNonZero);
7942*8975f5c5SAndroid Build Coastguard Worker return false;
7943*8975f5c5SAndroid Build Coastguard Worker }
7944*8975f5c5SAndroid Build Coastguard Worker if ((target == TextureType::_2DMultisample ||
7945*8975f5c5SAndroid Build Coastguard Worker target == TextureType::_2DMultisampleArray) &&
7946*8975f5c5SAndroid Build Coastguard Worker static_cast<GLuint>(params[0]) != 0)
7947*8975f5c5SAndroid Build Coastguard Worker {
7948*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelNonZero);
7949*8975f5c5SAndroid Build Coastguard Worker return false;
7950*8975f5c5SAndroid Build Coastguard Worker }
7951*8975f5c5SAndroid Build Coastguard Worker if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
7952*8975f5c5SAndroid Build Coastguard Worker {
7953*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelNonZero);
7954*8975f5c5SAndroid Build Coastguard Worker return false;
7955*8975f5c5SAndroid Build Coastguard Worker }
7956*8975f5c5SAndroid Build Coastguard Worker break;
7957*8975f5c5SAndroid Build Coastguard Worker
7958*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LEVEL:
7959*8975f5c5SAndroid Build Coastguard Worker if (ConvertToGLint(params[0]) < 0)
7960*8975f5c5SAndroid Build Coastguard Worker {
7961*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
7962*8975f5c5SAndroid Build Coastguard Worker return false;
7963*8975f5c5SAndroid Build Coastguard Worker }
7964*8975f5c5SAndroid Build Coastguard Worker break;
7965*8975f5c5SAndroid Build Coastguard Worker
7966*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_STENCIL_TEXTURE_MODE:
7967*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_1 &&
7968*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().stencilTexturingANGLE)
7969*8975f5c5SAndroid Build Coastguard Worker {
7970*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7971*8975f5c5SAndroid Build Coastguard Worker return false;
7972*8975f5c5SAndroid Build Coastguard Worker }
7973*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
7974*8975f5c5SAndroid Build Coastguard Worker {
7975*8975f5c5SAndroid Build Coastguard Worker case GL_DEPTH_COMPONENT:
7976*8975f5c5SAndroid Build Coastguard Worker case GL_STENCIL_INDEX:
7977*8975f5c5SAndroid Build Coastguard Worker break;
7978*8975f5c5SAndroid Build Coastguard Worker
7979*8975f5c5SAndroid Build Coastguard Worker default:
7980*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7981*8975f5c5SAndroid Build Coastguard Worker return false;
7982*8975f5c5SAndroid Build Coastguard Worker }
7983*8975f5c5SAndroid Build Coastguard Worker break;
7984*8975f5c5SAndroid Build Coastguard Worker
7985*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SRGB_DECODE_EXT:
7986*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params))
7987*8975f5c5SAndroid Build Coastguard Worker {
7988*8975f5c5SAndroid Build Coastguard Worker return false;
7989*8975f5c5SAndroid Build Coastguard Worker }
7990*8975f5c5SAndroid Build Coastguard Worker break;
7991*8975f5c5SAndroid Build Coastguard Worker
7992*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
7993*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureSRGBOverrideValue(context, entryPoint, params))
7994*8975f5c5SAndroid Build Coastguard Worker {
7995*8975f5c5SAndroid Build Coastguard Worker return false;
7996*8975f5c5SAndroid Build Coastguard Worker }
7997*8975f5c5SAndroid Build Coastguard Worker break;
7998*8975f5c5SAndroid Build Coastguard Worker
7999*8975f5c5SAndroid Build Coastguard Worker case GL_GENERATE_MIPMAP:
8000*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() > 1)
8001*8975f5c5SAndroid Build Coastguard Worker {
8002*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
8003*8975f5c5SAndroid Build Coastguard Worker return false;
8004*8975f5c5SAndroid Build Coastguard Worker }
8005*8975f5c5SAndroid Build Coastguard Worker break;
8006*8975f5c5SAndroid Build Coastguard Worker
8007*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CROP_RECT_OES:
8008*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() > 1)
8009*8975f5c5SAndroid Build Coastguard Worker {
8010*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
8011*8975f5c5SAndroid Build Coastguard Worker return false;
8012*8975f5c5SAndroid Build Coastguard Worker }
8013*8975f5c5SAndroid Build Coastguard Worker if (!vectorParams)
8014*8975f5c5SAndroid Build Coastguard Worker {
8015*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
8016*8975f5c5SAndroid Build Coastguard Worker return false;
8017*8975f5c5SAndroid Build Coastguard Worker }
8018*8975f5c5SAndroid Build Coastguard Worker break;
8019*8975f5c5SAndroid Build Coastguard Worker
8020*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BORDER_COLOR:
8021*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureBorderClampAny() &&
8022*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
8023*8975f5c5SAndroid Build Coastguard Worker {
8024*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
8025*8975f5c5SAndroid Build Coastguard Worker return false;
8026*8975f5c5SAndroid Build Coastguard Worker }
8027*8975f5c5SAndroid Build Coastguard Worker if (!vectorParams)
8028*8975f5c5SAndroid Build Coastguard Worker {
8029*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInsufficientBufferSize);
8030*8975f5c5SAndroid Build Coastguard Worker return false;
8031*8975f5c5SAndroid Build Coastguard Worker }
8032*8975f5c5SAndroid Build Coastguard Worker break;
8033*8975f5c5SAndroid Build Coastguard Worker
8034*8975f5c5SAndroid Build Coastguard Worker case GL_RESOURCE_INITIALIZED_ANGLE:
8035*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().robustResourceInitializationANGLE)
8036*8975f5c5SAndroid Build Coastguard Worker {
8037*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8038*8975f5c5SAndroid Build Coastguard Worker kRobustResourceInitializationExtensionRequired);
8039*8975f5c5SAndroid Build Coastguard Worker return false;
8040*8975f5c5SAndroid Build Coastguard Worker }
8041*8975f5c5SAndroid Build Coastguard Worker break;
8042*8975f5c5SAndroid Build Coastguard Worker
8043*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_PROTECTED_EXT:
8044*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().protectedTexturesEXT)
8045*8975f5c5SAndroid Build Coastguard Worker {
8046*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProtectedTexturesExtensionRequired);
8047*8975f5c5SAndroid Build Coastguard Worker return false;
8048*8975f5c5SAndroid Build Coastguard Worker }
8049*8975f5c5SAndroid Build Coastguard Worker if (ConvertToBool(params[0]) != context->getState().hasProtectedContent())
8050*8975f5c5SAndroid Build Coastguard Worker {
8051*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
8052*8975f5c5SAndroid Build Coastguard Worker "Protected Texture must match Protected Context");
8053*8975f5c5SAndroid Build Coastguard Worker return false;
8054*8975f5c5SAndroid Build Coastguard Worker }
8055*8975f5c5SAndroid Build Coastguard Worker break;
8056*8975f5c5SAndroid Build Coastguard Worker
8057*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERABILITY_VALIDATION_ANGLE:
8058*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().renderabilityValidationANGLE)
8059*8975f5c5SAndroid Build Coastguard Worker {
8060*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8061*8975f5c5SAndroid Build Coastguard Worker return false;
8062*8975f5c5SAndroid Build Coastguard Worker }
8063*8975f5c5SAndroid Build Coastguard Worker break;
8064*8975f5c5SAndroid Build Coastguard Worker
8065*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_TILING_EXT:
8066*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().memoryObjectEXT)
8067*8975f5c5SAndroid Build Coastguard Worker {
8068*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
8069*8975f5c5SAndroid Build Coastguard Worker return false;
8070*8975f5c5SAndroid Build Coastguard Worker }
8071*8975f5c5SAndroid Build Coastguard Worker switch (ConvertToGLenum(params[0]))
8072*8975f5c5SAndroid Build Coastguard Worker {
8073*8975f5c5SAndroid Build Coastguard Worker case GL_OPTIMAL_TILING_EXT:
8074*8975f5c5SAndroid Build Coastguard Worker case GL_LINEAR_TILING_EXT:
8075*8975f5c5SAndroid Build Coastguard Worker break;
8076*8975f5c5SAndroid Build Coastguard Worker
8077*8975f5c5SAndroid Build Coastguard Worker default:
8078*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(
8079*8975f5c5SAndroid Build Coastguard Worker GL_INVALID_OPERATION,
8080*8975f5c5SAndroid Build Coastguard Worker "Texture Tilling Mode must be OPTIMAL_TILING_EXT or LINEAR_TILING_EXT");
8081*8975f5c5SAndroid Build Coastguard Worker return false;
8082*8975f5c5SAndroid Build Coastguard Worker }
8083*8975f5c5SAndroid Build Coastguard Worker break;
8084*8975f5c5SAndroid Build Coastguard Worker
8085*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM:
8086*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureFoveatedQCOM)
8087*8975f5c5SAndroid Build Coastguard Worker {
8088*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
8089*8975f5c5SAndroid Build Coastguard Worker return false;
8090*8975f5c5SAndroid Build Coastguard Worker }
8091*8975f5c5SAndroid Build Coastguard Worker {
8092*8975f5c5SAndroid Build Coastguard Worker const GLuint features = static_cast<GLuint>(params[0]);
8093*8975f5c5SAndroid Build Coastguard Worker constexpr GLuint kSupportedFeatures = GL_FOVEATION_ENABLE_BIT_QCOM;
8094*8975f5c5SAndroid Build Coastguard Worker if (features != (features & kSupportedFeatures))
8095*8975f5c5SAndroid Build Coastguard Worker {
8096*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureInvalidParameters);
8097*8975f5c5SAndroid Build Coastguard Worker return false;
8098*8975f5c5SAndroid Build Coastguard Worker }
8099*8975f5c5SAndroid Build Coastguard Worker if ((context->getTextureByType(target)->getFoveatedFeatureBits() &
8100*8975f5c5SAndroid Build Coastguard Worker GL_FOVEATION_ENABLE_BIT_QCOM) &&
8101*8975f5c5SAndroid Build Coastguard Worker (features & GL_FOVEATION_ENABLE_BIT_QCOM) == 0)
8102*8975f5c5SAndroid Build Coastguard Worker {
8103*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFoveatedTextureCannotDisable);
8104*8975f5c5SAndroid Build Coastguard Worker return false;
8105*8975f5c5SAndroid Build Coastguard Worker }
8106*8975f5c5SAndroid Build Coastguard Worker }
8107*8975f5c5SAndroid Build Coastguard Worker break;
8108*8975f5c5SAndroid Build Coastguard Worker
8109*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM:
8110*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureFoveatedQCOM)
8111*8975f5c5SAndroid Build Coastguard Worker {
8112*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
8113*8975f5c5SAndroid Build Coastguard Worker return false;
8114*8975f5c5SAndroid Build Coastguard Worker }
8115*8975f5c5SAndroid Build Coastguard Worker if (static_cast<GLfloat>(params[0]) < 0.0 || static_cast<GLfloat>(params[0]) > 1.0)
8116*8975f5c5SAndroid Build Coastguard Worker {
8117*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFoveatedTextureInvalidPixelDensity);
8118*8975f5c5SAndroid Build Coastguard Worker return false;
8119*8975f5c5SAndroid Build Coastguard Worker }
8120*8975f5c5SAndroid Build Coastguard Worker break;
8121*8975f5c5SAndroid Build Coastguard Worker
8122*8975f5c5SAndroid Build Coastguard Worker default:
8123*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8124*8975f5c5SAndroid Build Coastguard Worker return false;
8125*8975f5c5SAndroid Build Coastguard Worker }
8126*8975f5c5SAndroid Build Coastguard Worker
8127*8975f5c5SAndroid Build Coastguard Worker return true;
8128*8975f5c5SAndroid Build Coastguard Worker }
8129*8975f5c5SAndroid Build Coastguard Worker
8130*8975f5c5SAndroid Build Coastguard Worker template bool ValidateTexParameterBase(const Context *,
8131*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint,
8132*8975f5c5SAndroid Build Coastguard Worker TextureType,
8133*8975f5c5SAndroid Build Coastguard Worker GLenum,
8134*8975f5c5SAndroid Build Coastguard Worker GLsizei,
8135*8975f5c5SAndroid Build Coastguard Worker bool,
8136*8975f5c5SAndroid Build Coastguard Worker const GLfloat *);
8137*8975f5c5SAndroid Build Coastguard Worker template bool ValidateTexParameterBase(const Context *,
8138*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint,
8139*8975f5c5SAndroid Build Coastguard Worker TextureType,
8140*8975f5c5SAndroid Build Coastguard Worker GLenum,
8141*8975f5c5SAndroid Build Coastguard Worker GLsizei,
8142*8975f5c5SAndroid Build Coastguard Worker bool,
8143*8975f5c5SAndroid Build Coastguard Worker const GLint *);
8144*8975f5c5SAndroid Build Coastguard Worker template bool ValidateTexParameterBase(const Context *,
8145*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint,
8146*8975f5c5SAndroid Build Coastguard Worker TextureType,
8147*8975f5c5SAndroid Build Coastguard Worker GLenum,
8148*8975f5c5SAndroid Build Coastguard Worker GLsizei,
8149*8975f5c5SAndroid Build Coastguard Worker bool,
8150*8975f5c5SAndroid Build Coastguard Worker const GLuint *);
8151*8975f5c5SAndroid Build Coastguard Worker
ValidateGetActiveUniformBlockivBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLsizei * length)8152*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetActiveUniformBlockivBase(const Context *context,
8153*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8154*8975f5c5SAndroid Build Coastguard Worker ShaderProgramID program,
8155*8975f5c5SAndroid Build Coastguard Worker UniformBlockIndex uniformBlockIndex,
8156*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
8157*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
8158*8975f5c5SAndroid Build Coastguard Worker {
8159*8975f5c5SAndroid Build Coastguard Worker if (length)
8160*8975f5c5SAndroid Build Coastguard Worker {
8161*8975f5c5SAndroid Build Coastguard Worker *length = 0;
8162*8975f5c5SAndroid Build Coastguard Worker }
8163*8975f5c5SAndroid Build Coastguard Worker
8164*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
8165*8975f5c5SAndroid Build Coastguard Worker {
8166*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8167*8975f5c5SAndroid Build Coastguard Worker return false;
8168*8975f5c5SAndroid Build Coastguard Worker }
8169*8975f5c5SAndroid Build Coastguard Worker
8170*8975f5c5SAndroid Build Coastguard Worker Program *programObject = GetValidProgram(context, entryPoint, program);
8171*8975f5c5SAndroid Build Coastguard Worker if (!programObject)
8172*8975f5c5SAndroid Build Coastguard Worker {
8173*8975f5c5SAndroid Build Coastguard Worker return false;
8174*8975f5c5SAndroid Build Coastguard Worker }
8175*8975f5c5SAndroid Build Coastguard Worker
8176*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable &executable = programObject->getExecutable();
8177*8975f5c5SAndroid Build Coastguard Worker if (uniformBlockIndex.value >= executable.getUniformBlocks().size())
8178*8975f5c5SAndroid Build Coastguard Worker {
8179*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsActiveUniformBlockCount);
8180*8975f5c5SAndroid Build Coastguard Worker return false;
8181*8975f5c5SAndroid Build Coastguard Worker }
8182*8975f5c5SAndroid Build Coastguard Worker
8183*8975f5c5SAndroid Build Coastguard Worker switch (pname)
8184*8975f5c5SAndroid Build Coastguard Worker {
8185*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_BINDING:
8186*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_DATA_SIZE:
8187*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_NAME_LENGTH:
8188*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
8189*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
8190*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
8191*8975f5c5SAndroid Build Coastguard Worker case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
8192*8975f5c5SAndroid Build Coastguard Worker break;
8193*8975f5c5SAndroid Build Coastguard Worker
8194*8975f5c5SAndroid Build Coastguard Worker default:
8195*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8196*8975f5c5SAndroid Build Coastguard Worker return false;
8197*8975f5c5SAndroid Build Coastguard Worker }
8198*8975f5c5SAndroid Build Coastguard Worker
8199*8975f5c5SAndroid Build Coastguard Worker if (length)
8200*8975f5c5SAndroid Build Coastguard Worker {
8201*8975f5c5SAndroid Build Coastguard Worker if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
8202*8975f5c5SAndroid Build Coastguard Worker {
8203*8975f5c5SAndroid Build Coastguard Worker const InterfaceBlock &uniformBlock =
8204*8975f5c5SAndroid Build Coastguard Worker executable.getUniformBlockByIndex(uniformBlockIndex.value);
8205*8975f5c5SAndroid Build Coastguard Worker *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
8206*8975f5c5SAndroid Build Coastguard Worker }
8207*8975f5c5SAndroid Build Coastguard Worker else
8208*8975f5c5SAndroid Build Coastguard Worker {
8209*8975f5c5SAndroid Build Coastguard Worker *length = 1;
8210*8975f5c5SAndroid Build Coastguard Worker }
8211*8975f5c5SAndroid Build Coastguard Worker }
8212*8975f5c5SAndroid Build Coastguard Worker
8213*8975f5c5SAndroid Build Coastguard Worker return true;
8214*8975f5c5SAndroid Build Coastguard Worker }
8215*8975f5c5SAndroid Build Coastguard Worker
8216*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateSamplerParameterBase(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,bool vectorParams,const ParamType * params)8217*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterBase(const Context *context,
8218*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8219*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
8220*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
8221*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
8222*8975f5c5SAndroid Build Coastguard Worker bool vectorParams,
8223*8975f5c5SAndroid Build Coastguard Worker const ParamType *params)
8224*8975f5c5SAndroid Build Coastguard Worker {
8225*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
8226*8975f5c5SAndroid Build Coastguard Worker {
8227*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8228*8975f5c5SAndroid Build Coastguard Worker return false;
8229*8975f5c5SAndroid Build Coastguard Worker }
8230*8975f5c5SAndroid Build Coastguard Worker
8231*8975f5c5SAndroid Build Coastguard Worker if (!context->isSampler(sampler))
8232*8975f5c5SAndroid Build Coastguard Worker {
8233*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSampler);
8234*8975f5c5SAndroid Build Coastguard Worker return false;
8235*8975f5c5SAndroid Build Coastguard Worker }
8236*8975f5c5SAndroid Build Coastguard Worker
8237*8975f5c5SAndroid Build Coastguard Worker const GLsizei minBufSize = GetSamplerParameterCount(pname);
8238*8975f5c5SAndroid Build Coastguard Worker if (bufSize >= 0 && bufSize < minBufSize)
8239*8975f5c5SAndroid Build Coastguard Worker {
8240*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
8241*8975f5c5SAndroid Build Coastguard Worker return false;
8242*8975f5c5SAndroid Build Coastguard Worker }
8243*8975f5c5SAndroid Build Coastguard Worker
8244*8975f5c5SAndroid Build Coastguard Worker switch (pname)
8245*8975f5c5SAndroid Build Coastguard Worker {
8246*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_S:
8247*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_T:
8248*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
8249*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureWrapModeValue(context, entryPoint, params, false))
8250*8975f5c5SAndroid Build Coastguard Worker {
8251*8975f5c5SAndroid Build Coastguard Worker return false;
8252*8975f5c5SAndroid Build Coastguard Worker }
8253*8975f5c5SAndroid Build Coastguard Worker break;
8254*8975f5c5SAndroid Build Coastguard Worker
8255*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_FILTER:
8256*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMinFilterValue(context, entryPoint, params, false))
8257*8975f5c5SAndroid Build Coastguard Worker {
8258*8975f5c5SAndroid Build Coastguard Worker return false;
8259*8975f5c5SAndroid Build Coastguard Worker }
8260*8975f5c5SAndroid Build Coastguard Worker break;
8261*8975f5c5SAndroid Build Coastguard Worker
8262*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAG_FILTER:
8263*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMagFilterValue(context, entryPoint, params))
8264*8975f5c5SAndroid Build Coastguard Worker {
8265*8975f5c5SAndroid Build Coastguard Worker return false;
8266*8975f5c5SAndroid Build Coastguard Worker }
8267*8975f5c5SAndroid Build Coastguard Worker break;
8268*8975f5c5SAndroid Build Coastguard Worker
8269*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_LOD:
8270*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LOD:
8271*8975f5c5SAndroid Build Coastguard Worker // any value is permissible
8272*8975f5c5SAndroid Build Coastguard Worker break;
8273*8975f5c5SAndroid Build Coastguard Worker
8274*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_MODE:
8275*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureCompareModeValue(context, entryPoint, params))
8276*8975f5c5SAndroid Build Coastguard Worker {
8277*8975f5c5SAndroid Build Coastguard Worker return false;
8278*8975f5c5SAndroid Build Coastguard Worker }
8279*8975f5c5SAndroid Build Coastguard Worker break;
8280*8975f5c5SAndroid Build Coastguard Worker
8281*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_FUNC:
8282*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureCompareFuncValue(context, entryPoint, params))
8283*8975f5c5SAndroid Build Coastguard Worker {
8284*8975f5c5SAndroid Build Coastguard Worker return false;
8285*8975f5c5SAndroid Build Coastguard Worker }
8286*8975f5c5SAndroid Build Coastguard Worker break;
8287*8975f5c5SAndroid Build Coastguard Worker
8288*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SRGB_DECODE_EXT:
8289*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params))
8290*8975f5c5SAndroid Build Coastguard Worker {
8291*8975f5c5SAndroid Build Coastguard Worker return false;
8292*8975f5c5SAndroid Build Coastguard Worker }
8293*8975f5c5SAndroid Build Coastguard Worker break;
8294*8975f5c5SAndroid Build Coastguard Worker
8295*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_ANISOTROPY_EXT:
8296*8975f5c5SAndroid Build Coastguard Worker {
8297*8975f5c5SAndroid Build Coastguard Worker GLfloat paramValue = static_cast<GLfloat>(params[0]);
8298*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue))
8299*8975f5c5SAndroid Build Coastguard Worker {
8300*8975f5c5SAndroid Build Coastguard Worker return false;
8301*8975f5c5SAndroid Build Coastguard Worker }
8302*8975f5c5SAndroid Build Coastguard Worker }
8303*8975f5c5SAndroid Build Coastguard Worker break;
8304*8975f5c5SAndroid Build Coastguard Worker
8305*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BORDER_COLOR:
8306*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureBorderClampAny() &&
8307*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
8308*8975f5c5SAndroid Build Coastguard Worker {
8309*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
8310*8975f5c5SAndroid Build Coastguard Worker return false;
8311*8975f5c5SAndroid Build Coastguard Worker }
8312*8975f5c5SAndroid Build Coastguard Worker if (!vectorParams)
8313*8975f5c5SAndroid Build Coastguard Worker {
8314*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInsufficientBufferSize);
8315*8975f5c5SAndroid Build Coastguard Worker return false;
8316*8975f5c5SAndroid Build Coastguard Worker }
8317*8975f5c5SAndroid Build Coastguard Worker break;
8318*8975f5c5SAndroid Build Coastguard Worker
8319*8975f5c5SAndroid Build Coastguard Worker default:
8320*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8321*8975f5c5SAndroid Build Coastguard Worker return false;
8322*8975f5c5SAndroid Build Coastguard Worker }
8323*8975f5c5SAndroid Build Coastguard Worker
8324*8975f5c5SAndroid Build Coastguard Worker return true;
8325*8975f5c5SAndroid Build Coastguard Worker }
8326*8975f5c5SAndroid Build Coastguard Worker
8327*8975f5c5SAndroid Build Coastguard Worker template bool ValidateSamplerParameterBase(const Context *,
8328*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint,
8329*8975f5c5SAndroid Build Coastguard Worker SamplerID,
8330*8975f5c5SAndroid Build Coastguard Worker GLenum,
8331*8975f5c5SAndroid Build Coastguard Worker GLsizei,
8332*8975f5c5SAndroid Build Coastguard Worker bool,
8333*8975f5c5SAndroid Build Coastguard Worker const GLfloat *);
8334*8975f5c5SAndroid Build Coastguard Worker template bool ValidateSamplerParameterBase(const Context *,
8335*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint,
8336*8975f5c5SAndroid Build Coastguard Worker SamplerID,
8337*8975f5c5SAndroid Build Coastguard Worker GLenum,
8338*8975f5c5SAndroid Build Coastguard Worker GLsizei,
8339*8975f5c5SAndroid Build Coastguard Worker bool,
8340*8975f5c5SAndroid Build Coastguard Worker const GLint *);
8341*8975f5c5SAndroid Build Coastguard Worker template bool ValidateSamplerParameterBase(const Context *,
8342*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint,
8343*8975f5c5SAndroid Build Coastguard Worker SamplerID,
8344*8975f5c5SAndroid Build Coastguard Worker GLenum,
8345*8975f5c5SAndroid Build Coastguard Worker GLsizei,
8346*8975f5c5SAndroid Build Coastguard Worker bool,
8347*8975f5c5SAndroid Build Coastguard Worker const GLuint *);
8348*8975f5c5SAndroid Build Coastguard Worker
ValidateGetSamplerParameterBase(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei * length)8349*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterBase(const Context *context,
8350*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8351*8975f5c5SAndroid Build Coastguard Worker SamplerID sampler,
8352*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
8353*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
8354*8975f5c5SAndroid Build Coastguard Worker {
8355*8975f5c5SAndroid Build Coastguard Worker if (length)
8356*8975f5c5SAndroid Build Coastguard Worker {
8357*8975f5c5SAndroid Build Coastguard Worker *length = 0;
8358*8975f5c5SAndroid Build Coastguard Worker }
8359*8975f5c5SAndroid Build Coastguard Worker
8360*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
8361*8975f5c5SAndroid Build Coastguard Worker {
8362*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8363*8975f5c5SAndroid Build Coastguard Worker return false;
8364*8975f5c5SAndroid Build Coastguard Worker }
8365*8975f5c5SAndroid Build Coastguard Worker
8366*8975f5c5SAndroid Build Coastguard Worker if (!context->isSampler(sampler))
8367*8975f5c5SAndroid Build Coastguard Worker {
8368*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSampler);
8369*8975f5c5SAndroid Build Coastguard Worker return false;
8370*8975f5c5SAndroid Build Coastguard Worker }
8371*8975f5c5SAndroid Build Coastguard Worker
8372*8975f5c5SAndroid Build Coastguard Worker switch (pname)
8373*8975f5c5SAndroid Build Coastguard Worker {
8374*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_S:
8375*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_T:
8376*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WRAP_R:
8377*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_FILTER:
8378*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAG_FILTER:
8379*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MIN_LOD:
8380*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_LOD:
8381*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_MODE:
8382*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPARE_FUNC:
8383*8975f5c5SAndroid Build Coastguard Worker break;
8384*8975f5c5SAndroid Build Coastguard Worker
8385*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_MAX_ANISOTROPY_EXT:
8386*8975f5c5SAndroid Build Coastguard Worker if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
8387*8975f5c5SAndroid Build Coastguard Worker {
8388*8975f5c5SAndroid Build Coastguard Worker return false;
8389*8975f5c5SAndroid Build Coastguard Worker }
8390*8975f5c5SAndroid Build Coastguard Worker break;
8391*8975f5c5SAndroid Build Coastguard Worker
8392*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SRGB_DECODE_EXT:
8393*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureSRGBDecodeEXT)
8394*8975f5c5SAndroid Build Coastguard Worker {
8395*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8396*8975f5c5SAndroid Build Coastguard Worker return false;
8397*8975f5c5SAndroid Build Coastguard Worker }
8398*8975f5c5SAndroid Build Coastguard Worker break;
8399*8975f5c5SAndroid Build Coastguard Worker
8400*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BORDER_COLOR:
8401*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureBorderClampAny() &&
8402*8975f5c5SAndroid Build Coastguard Worker context->getClientVersion() < ES_3_2)
8403*8975f5c5SAndroid Build Coastguard Worker {
8404*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
8405*8975f5c5SAndroid Build Coastguard Worker return false;
8406*8975f5c5SAndroid Build Coastguard Worker }
8407*8975f5c5SAndroid Build Coastguard Worker break;
8408*8975f5c5SAndroid Build Coastguard Worker
8409*8975f5c5SAndroid Build Coastguard Worker default:
8410*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8411*8975f5c5SAndroid Build Coastguard Worker return false;
8412*8975f5c5SAndroid Build Coastguard Worker }
8413*8975f5c5SAndroid Build Coastguard Worker
8414*8975f5c5SAndroid Build Coastguard Worker if (length)
8415*8975f5c5SAndroid Build Coastguard Worker {
8416*8975f5c5SAndroid Build Coastguard Worker *length = GetSamplerParameterCount(pname);
8417*8975f5c5SAndroid Build Coastguard Worker }
8418*8975f5c5SAndroid Build Coastguard Worker return true;
8419*8975f5c5SAndroid Build Coastguard Worker }
8420*8975f5c5SAndroid Build Coastguard Worker
ValidateGetInternalFormativBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLsizei * numParams)8421*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetInternalFormativBase(const Context *context,
8422*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8423*8975f5c5SAndroid Build Coastguard Worker GLenum target,
8424*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
8425*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
8426*8975f5c5SAndroid Build Coastguard Worker GLsizei bufSize,
8427*8975f5c5SAndroid Build Coastguard Worker GLsizei *numParams)
8428*8975f5c5SAndroid Build Coastguard Worker {
8429*8975f5c5SAndroid Build Coastguard Worker if (numParams)
8430*8975f5c5SAndroid Build Coastguard Worker {
8431*8975f5c5SAndroid Build Coastguard Worker *numParams = 0;
8432*8975f5c5SAndroid Build Coastguard Worker }
8433*8975f5c5SAndroid Build Coastguard Worker
8434*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() < 3)
8435*8975f5c5SAndroid Build Coastguard Worker {
8436*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8437*8975f5c5SAndroid Build Coastguard Worker return false;
8438*8975f5c5SAndroid Build Coastguard Worker }
8439*8975f5c5SAndroid Build Coastguard Worker
8440*8975f5c5SAndroid Build Coastguard Worker const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
8441*8975f5c5SAndroid Build Coastguard Worker if (!formatCaps.renderbuffer)
8442*8975f5c5SAndroid Build Coastguard Worker {
8443*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFormatNotRenderable);
8444*8975f5c5SAndroid Build Coastguard Worker return false;
8445*8975f5c5SAndroid Build Coastguard Worker }
8446*8975f5c5SAndroid Build Coastguard Worker
8447*8975f5c5SAndroid Build Coastguard Worker switch (target)
8448*8975f5c5SAndroid Build Coastguard Worker {
8449*8975f5c5SAndroid Build Coastguard Worker case GL_RENDERBUFFER:
8450*8975f5c5SAndroid Build Coastguard Worker break;
8451*8975f5c5SAndroid Build Coastguard Worker
8452*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE:
8453*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_1 &&
8454*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().textureMultisampleANGLE)
8455*8975f5c5SAndroid Build Coastguard Worker {
8456*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
8457*8975f5c5SAndroid Build Coastguard Worker return false;
8458*8975f5c5SAndroid Build Coastguard Worker }
8459*8975f5c5SAndroid Build Coastguard Worker break;
8460*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
8461*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_2 &&
8462*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().textureStorageMultisample2dArrayOES)
8463*8975f5c5SAndroid Build Coastguard Worker {
8464*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleArrayExtensionOrES32Required);
8465*8975f5c5SAndroid Build Coastguard Worker return false;
8466*8975f5c5SAndroid Build Coastguard Worker }
8467*8975f5c5SAndroid Build Coastguard Worker break;
8468*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D:
8469*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_CUBE_MAP:
8470*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_3D:
8471*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_2D_ARRAY:
8472*8975f5c5SAndroid Build Coastguard Worker if (pname != GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT &&
8473*8975f5c5SAndroid Build Coastguard Worker pname != GL_SURFACE_COMPRESSION_EXT)
8474*8975f5c5SAndroid Build Coastguard Worker {
8475*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8476*8975f5c5SAndroid Build Coastguard Worker return false;
8477*8975f5c5SAndroid Build Coastguard Worker }
8478*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureStorageCompressionEXT)
8479*8975f5c5SAndroid Build Coastguard Worker {
8480*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8481*8975f5c5SAndroid Build Coastguard Worker kTextureStorageCompressionExtensionRequired);
8482*8975f5c5SAndroid Build Coastguard Worker return false;
8483*8975f5c5SAndroid Build Coastguard Worker }
8484*8975f5c5SAndroid Build Coastguard Worker break;
8485*8975f5c5SAndroid Build Coastguard Worker default:
8486*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8487*8975f5c5SAndroid Build Coastguard Worker return false;
8488*8975f5c5SAndroid Build Coastguard Worker }
8489*8975f5c5SAndroid Build Coastguard Worker
8490*8975f5c5SAndroid Build Coastguard Worker if (bufSize < 0)
8491*8975f5c5SAndroid Build Coastguard Worker {
8492*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInsufficientBufferSize);
8493*8975f5c5SAndroid Build Coastguard Worker return false;
8494*8975f5c5SAndroid Build Coastguard Worker }
8495*8975f5c5SAndroid Build Coastguard Worker
8496*8975f5c5SAndroid Build Coastguard Worker GLsizei maxWriteParams = 0;
8497*8975f5c5SAndroid Build Coastguard Worker switch (pname)
8498*8975f5c5SAndroid Build Coastguard Worker {
8499*8975f5c5SAndroid Build Coastguard Worker case GL_NUM_SAMPLE_COUNTS:
8500*8975f5c5SAndroid Build Coastguard Worker maxWriteParams = 1;
8501*8975f5c5SAndroid Build Coastguard Worker break;
8502*8975f5c5SAndroid Build Coastguard Worker
8503*8975f5c5SAndroid Build Coastguard Worker case GL_SAMPLES:
8504*8975f5c5SAndroid Build Coastguard Worker maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
8505*8975f5c5SAndroid Build Coastguard Worker break;
8506*8975f5c5SAndroid Build Coastguard Worker
8507*8975f5c5SAndroid Build Coastguard Worker case GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT:
8508*8975f5c5SAndroid Build Coastguard Worker case GL_SURFACE_COMPRESSION_EXT:
8509*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureStorageCompressionEXT)
8510*8975f5c5SAndroid Build Coastguard Worker {
8511*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8512*8975f5c5SAndroid Build Coastguard Worker kTextureStorageCompressionExtensionRequired);
8513*8975f5c5SAndroid Build Coastguard Worker return false;
8514*8975f5c5SAndroid Build Coastguard Worker }
8515*8975f5c5SAndroid Build Coastguard Worker break;
8516*8975f5c5SAndroid Build Coastguard Worker
8517*8975f5c5SAndroid Build Coastguard Worker default:
8518*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8519*8975f5c5SAndroid Build Coastguard Worker return false;
8520*8975f5c5SAndroid Build Coastguard Worker }
8521*8975f5c5SAndroid Build Coastguard Worker
8522*8975f5c5SAndroid Build Coastguard Worker if (numParams)
8523*8975f5c5SAndroid Build Coastguard Worker {
8524*8975f5c5SAndroid Build Coastguard Worker // glGetInternalFormativ will not overflow bufSize
8525*8975f5c5SAndroid Build Coastguard Worker *numParams = std::min(bufSize, maxWriteParams);
8526*8975f5c5SAndroid Build Coastguard Worker }
8527*8975f5c5SAndroid Build Coastguard Worker
8528*8975f5c5SAndroid Build Coastguard Worker return true;
8529*8975f5c5SAndroid Build Coastguard Worker }
8530*8975f5c5SAndroid Build Coastguard Worker
ValidateFramebufferNotMultisampled(const Context * context,angle::EntryPoint entryPoint,const Framebuffer * framebuffer,bool checkReadBufferResourceSamples)8531*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferNotMultisampled(const Context *context,
8532*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8533*8975f5c5SAndroid Build Coastguard Worker const Framebuffer *framebuffer,
8534*8975f5c5SAndroid Build Coastguard Worker bool checkReadBufferResourceSamples)
8535*8975f5c5SAndroid Build Coastguard Worker {
8536*8975f5c5SAndroid Build Coastguard Worker int samples = checkReadBufferResourceSamples
8537*8975f5c5SAndroid Build Coastguard Worker ? framebuffer->getReadBufferResourceSamples(context)
8538*8975f5c5SAndroid Build Coastguard Worker : framebuffer->getSamples(context);
8539*8975f5c5SAndroid Build Coastguard Worker if (samples != 0)
8540*8975f5c5SAndroid Build Coastguard Worker {
8541*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
8542*8975f5c5SAndroid Build Coastguard Worker return false;
8543*8975f5c5SAndroid Build Coastguard Worker }
8544*8975f5c5SAndroid Build Coastguard Worker return true;
8545*8975f5c5SAndroid Build Coastguard Worker }
8546*8975f5c5SAndroid Build Coastguard Worker
ValidateMultitextureUnit(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum texture)8547*8975f5c5SAndroid Build Coastguard Worker bool ValidateMultitextureUnit(const PrivateState &state,
8548*8975f5c5SAndroid Build Coastguard Worker ErrorSet *errors,
8549*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8550*8975f5c5SAndroid Build Coastguard Worker GLenum texture)
8551*8975f5c5SAndroid Build Coastguard Worker {
8552*8975f5c5SAndroid Build Coastguard Worker if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + state.getCaps().maxMultitextureUnits)
8553*8975f5c5SAndroid Build Coastguard Worker {
8554*8975f5c5SAndroid Build Coastguard Worker errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMultitextureUnit);
8555*8975f5c5SAndroid Build Coastguard Worker return false;
8556*8975f5c5SAndroid Build Coastguard Worker }
8557*8975f5c5SAndroid Build Coastguard Worker return true;
8558*8975f5c5SAndroid Build Coastguard Worker }
8559*8975f5c5SAndroid Build Coastguard Worker
ValidateTexStorageMultisample(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLint internalFormat,GLsizei width,GLsizei height)8560*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexStorageMultisample(const Context *context,
8561*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8562*8975f5c5SAndroid Build Coastguard Worker TextureType target,
8563*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
8564*8975f5c5SAndroid Build Coastguard Worker GLint internalFormat,
8565*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
8566*8975f5c5SAndroid Build Coastguard Worker GLsizei height)
8567*8975f5c5SAndroid Build Coastguard Worker {
8568*8975f5c5SAndroid Build Coastguard Worker const Caps &caps = context->getCaps();
8569*8975f5c5SAndroid Build Coastguard Worker if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
8570*8975f5c5SAndroid Build Coastguard Worker {
8571*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
8572*8975f5c5SAndroid Build Coastguard Worker return false;
8573*8975f5c5SAndroid Build Coastguard Worker }
8574*8975f5c5SAndroid Build Coastguard Worker
8575*8975f5c5SAndroid Build Coastguard Worker if (samples == 0)
8576*8975f5c5SAndroid Build Coastguard Worker {
8577*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplesZero);
8578*8975f5c5SAndroid Build Coastguard Worker return false;
8579*8975f5c5SAndroid Build Coastguard Worker }
8580*8975f5c5SAndroid Build Coastguard Worker
8581*8975f5c5SAndroid Build Coastguard Worker const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
8582*8975f5c5SAndroid Build Coastguard Worker if (!formatCaps.textureAttachment)
8583*8975f5c5SAndroid Build Coastguard Worker {
8584*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRenderableInternalFormat);
8585*8975f5c5SAndroid Build Coastguard Worker return false;
8586*8975f5c5SAndroid Build Coastguard Worker }
8587*8975f5c5SAndroid Build Coastguard Worker
8588*8975f5c5SAndroid Build Coastguard Worker // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
8589*8975f5c5SAndroid Build Coastguard Worker // is one of the unsized base internalformats listed in table 8.11.
8590*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
8591*8975f5c5SAndroid Build Coastguard Worker if (formatInfo.internalFormat == GL_NONE)
8592*8975f5c5SAndroid Build Coastguard Worker {
8593*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
8594*8975f5c5SAndroid Build Coastguard Worker return false;
8595*8975f5c5SAndroid Build Coastguard Worker }
8596*8975f5c5SAndroid Build Coastguard Worker
8597*8975f5c5SAndroid Build Coastguard Worker if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
8598*8975f5c5SAndroid Build Coastguard Worker {
8599*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
8600*8975f5c5SAndroid Build Coastguard Worker return false;
8601*8975f5c5SAndroid Build Coastguard Worker }
8602*8975f5c5SAndroid Build Coastguard Worker
8603*8975f5c5SAndroid Build Coastguard Worker Texture *texture = context->getTextureByType(target);
8604*8975f5c5SAndroid Build Coastguard Worker if (!texture || texture->id().value == 0)
8605*8975f5c5SAndroid Build Coastguard Worker {
8606*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kZeroBoundToTarget);
8607*8975f5c5SAndroid Build Coastguard Worker return false;
8608*8975f5c5SAndroid Build Coastguard Worker }
8609*8975f5c5SAndroid Build Coastguard Worker
8610*8975f5c5SAndroid Build Coastguard Worker if (texture->getImmutableFormat())
8611*8975f5c5SAndroid Build Coastguard Worker {
8612*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImmutableTextureBound);
8613*8975f5c5SAndroid Build Coastguard Worker return false;
8614*8975f5c5SAndroid Build Coastguard Worker }
8615*8975f5c5SAndroid Build Coastguard Worker return true;
8616*8975f5c5SAndroid Build Coastguard Worker }
8617*8975f5c5SAndroid Build Coastguard Worker
ValidateTexStorage2DMultisampleBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLint internalFormat,GLsizei width,GLsizei height)8618*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexStorage2DMultisampleBase(const Context *context,
8619*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8620*8975f5c5SAndroid Build Coastguard Worker TextureType target,
8621*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
8622*8975f5c5SAndroid Build Coastguard Worker GLint internalFormat,
8623*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
8624*8975f5c5SAndroid Build Coastguard Worker GLsizei height)
8625*8975f5c5SAndroid Build Coastguard Worker {
8626*8975f5c5SAndroid Build Coastguard Worker if (target != TextureType::_2DMultisample)
8627*8975f5c5SAndroid Build Coastguard Worker {
8628*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8629*8975f5c5SAndroid Build Coastguard Worker return false;
8630*8975f5c5SAndroid Build Coastguard Worker }
8631*8975f5c5SAndroid Build Coastguard Worker
8632*8975f5c5SAndroid Build Coastguard Worker if (width < 1 || height < 1)
8633*8975f5c5SAndroid Build Coastguard Worker {
8634*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
8635*8975f5c5SAndroid Build Coastguard Worker return false;
8636*8975f5c5SAndroid Build Coastguard Worker }
8637*8975f5c5SAndroid Build Coastguard Worker
8638*8975f5c5SAndroid Build Coastguard Worker return ValidateTexStorageMultisample(context, entryPoint, target, samples, internalFormat,
8639*8975f5c5SAndroid Build Coastguard Worker width, height);
8640*8975f5c5SAndroid Build Coastguard Worker }
8641*8975f5c5SAndroid Build Coastguard Worker
ValidateTexStorage3DMultisampleBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)8642*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexStorage3DMultisampleBase(const Context *context,
8643*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8644*8975f5c5SAndroid Build Coastguard Worker TextureType target,
8645*8975f5c5SAndroid Build Coastguard Worker GLsizei samples,
8646*8975f5c5SAndroid Build Coastguard Worker GLenum internalformat,
8647*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
8648*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
8649*8975f5c5SAndroid Build Coastguard Worker GLsizei depth)
8650*8975f5c5SAndroid Build Coastguard Worker {
8651*8975f5c5SAndroid Build Coastguard Worker if (target != TextureType::_2DMultisampleArray)
8652*8975f5c5SAndroid Build Coastguard Worker {
8653*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8654*8975f5c5SAndroid Build Coastguard Worker return false;
8655*8975f5c5SAndroid Build Coastguard Worker }
8656*8975f5c5SAndroid Build Coastguard Worker
8657*8975f5c5SAndroid Build Coastguard Worker if (width < 1 || height < 1 || depth < 1)
8658*8975f5c5SAndroid Build Coastguard Worker {
8659*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
8660*8975f5c5SAndroid Build Coastguard Worker return false;
8661*8975f5c5SAndroid Build Coastguard Worker }
8662*8975f5c5SAndroid Build Coastguard Worker
8663*8975f5c5SAndroid Build Coastguard Worker if (depth > context->getCaps().maxArrayTextureLayers)
8664*8975f5c5SAndroid Build Coastguard Worker {
8665*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureDepthOutOfRange);
8666*8975f5c5SAndroid Build Coastguard Worker return false;
8667*8975f5c5SAndroid Build Coastguard Worker }
8668*8975f5c5SAndroid Build Coastguard Worker
8669*8975f5c5SAndroid Build Coastguard Worker return ValidateTexStorageMultisample(context, entryPoint, target, samples, internalformat,
8670*8975f5c5SAndroid Build Coastguard Worker width, height);
8671*8975f5c5SAndroid Build Coastguard Worker }
8672*8975f5c5SAndroid Build Coastguard Worker
ValidateGetTexLevelParameterBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum pname,GLsizei * length)8673*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexLevelParameterBase(const Context *context,
8674*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8675*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
8676*8975f5c5SAndroid Build Coastguard Worker GLint level,
8677*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
8678*8975f5c5SAndroid Build Coastguard Worker GLsizei *length)
8679*8975f5c5SAndroid Build Coastguard Worker {
8680*8975f5c5SAndroid Build Coastguard Worker
8681*8975f5c5SAndroid Build Coastguard Worker if (length)
8682*8975f5c5SAndroid Build Coastguard Worker {
8683*8975f5c5SAndroid Build Coastguard Worker *length = 0;
8684*8975f5c5SAndroid Build Coastguard Worker }
8685*8975f5c5SAndroid Build Coastguard Worker
8686*8975f5c5SAndroid Build Coastguard Worker TextureType type = TextureTargetToType(target);
8687*8975f5c5SAndroid Build Coastguard Worker
8688*8975f5c5SAndroid Build Coastguard Worker if (!ValidTexLevelDestinationTarget(context, type))
8689*8975f5c5SAndroid Build Coastguard Worker {
8690*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
8691*8975f5c5SAndroid Build Coastguard Worker return false;
8692*8975f5c5SAndroid Build Coastguard Worker }
8693*8975f5c5SAndroid Build Coastguard Worker
8694*8975f5c5SAndroid Build Coastguard Worker // If type is valid, the texture object must exist
8695*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getTextureByType(type) != nullptr);
8696*8975f5c5SAndroid Build Coastguard Worker
8697*8975f5c5SAndroid Build Coastguard Worker if (!ValidMipLevel(context, type, level))
8698*8975f5c5SAndroid Build Coastguard Worker {
8699*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
8700*8975f5c5SAndroid Build Coastguard Worker return false;
8701*8975f5c5SAndroid Build Coastguard Worker }
8702*8975f5c5SAndroid Build Coastguard Worker
8703*8975f5c5SAndroid Build Coastguard Worker switch (pname)
8704*8975f5c5SAndroid Build Coastguard Worker {
8705*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_RED_TYPE:
8706*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_GREEN_TYPE:
8707*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BLUE_TYPE:
8708*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_ALPHA_TYPE:
8709*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_DEPTH_TYPE:
8710*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_RED_SIZE:
8711*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_GREEN_SIZE:
8712*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BLUE_SIZE:
8713*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_ALPHA_SIZE:
8714*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_DEPTH_SIZE:
8715*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_STENCIL_SIZE:
8716*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SHARED_SIZE:
8717*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_INTERNAL_FORMAT:
8718*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_WIDTH:
8719*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_HEIGHT:
8720*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_COMPRESSED:
8721*8975f5c5SAndroid Build Coastguard Worker break;
8722*8975f5c5SAndroid Build Coastguard Worker
8723*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_DEPTH:
8724*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_0 && !context->getExtensions().texture3DOES)
8725*8975f5c5SAndroid Build Coastguard Worker {
8726*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumNotSupported);
8727*8975f5c5SAndroid Build Coastguard Worker return false;
8728*8975f5c5SAndroid Build Coastguard Worker }
8729*8975f5c5SAndroid Build Coastguard Worker break;
8730*8975f5c5SAndroid Build Coastguard Worker
8731*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_SAMPLES:
8732*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
8733*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < ES_3_1 &&
8734*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().textureMultisampleANGLE)
8735*8975f5c5SAndroid Build Coastguard Worker {
8736*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
8737*8975f5c5SAndroid Build Coastguard Worker return false;
8738*8975f5c5SAndroid Build Coastguard Worker }
8739*8975f5c5SAndroid Build Coastguard Worker break;
8740*8975f5c5SAndroid Build Coastguard Worker
8741*8975f5c5SAndroid Build Coastguard Worker case GL_RESOURCE_INITIALIZED_ANGLE:
8742*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().robustResourceInitializationANGLE)
8743*8975f5c5SAndroid Build Coastguard Worker {
8744*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8745*8975f5c5SAndroid Build Coastguard Worker kRobustResourceInitializationExtensionRequired);
8746*8975f5c5SAndroid Build Coastguard Worker return false;
8747*8975f5c5SAndroid Build Coastguard Worker }
8748*8975f5c5SAndroid Build Coastguard Worker break;
8749*8975f5c5SAndroid Build Coastguard Worker
8750*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
8751*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER_OFFSET:
8752*8975f5c5SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER_SIZE:
8753*8975f5c5SAndroid Build Coastguard Worker if (context->getClientVersion() < Version(3, 2) &&
8754*8975f5c5SAndroid Build Coastguard Worker !context->getExtensions().textureBufferAny())
8755*8975f5c5SAndroid Build Coastguard Worker {
8756*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferExtensionNotAvailable);
8757*8975f5c5SAndroid Build Coastguard Worker return false;
8758*8975f5c5SAndroid Build Coastguard Worker }
8759*8975f5c5SAndroid Build Coastguard Worker break;
8760*8975f5c5SAndroid Build Coastguard Worker
8761*8975f5c5SAndroid Build Coastguard Worker default:
8762*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
8763*8975f5c5SAndroid Build Coastguard Worker return false;
8764*8975f5c5SAndroid Build Coastguard Worker }
8765*8975f5c5SAndroid Build Coastguard Worker
8766*8975f5c5SAndroid Build Coastguard Worker if (length)
8767*8975f5c5SAndroid Build Coastguard Worker {
8768*8975f5c5SAndroid Build Coastguard Worker *length = 1;
8769*8975f5c5SAndroid Build Coastguard Worker }
8770*8975f5c5SAndroid Build Coastguard Worker return true;
8771*8975f5c5SAndroid Build Coastguard Worker }
8772*8975f5c5SAndroid Build Coastguard Worker
ValidateGetMultisamplefvBase(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLuint index,const GLfloat * val)8773*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetMultisamplefvBase(const Context *context,
8774*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8775*8975f5c5SAndroid Build Coastguard Worker GLenum pname,
8776*8975f5c5SAndroid Build Coastguard Worker GLuint index,
8777*8975f5c5SAndroid Build Coastguard Worker const GLfloat *val)
8778*8975f5c5SAndroid Build Coastguard Worker {
8779*8975f5c5SAndroid Build Coastguard Worker if (pname != GL_SAMPLE_POSITION)
8780*8975f5c5SAndroid Build Coastguard Worker {
8781*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
8782*8975f5c5SAndroid Build Coastguard Worker return false;
8783*8975f5c5SAndroid Build Coastguard Worker }
8784*8975f5c5SAndroid Build Coastguard Worker
8785*8975f5c5SAndroid Build Coastguard Worker Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
8786*8975f5c5SAndroid Build Coastguard Worker GLint samples = framebuffer->getSamples(context);
8787*8975f5c5SAndroid Build Coastguard Worker
8788*8975f5c5SAndroid Build Coastguard Worker if (index >= static_cast<GLuint>(samples))
8789*8975f5c5SAndroid Build Coastguard Worker {
8790*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsSamples);
8791*8975f5c5SAndroid Build Coastguard Worker return false;
8792*8975f5c5SAndroid Build Coastguard Worker }
8793*8975f5c5SAndroid Build Coastguard Worker
8794*8975f5c5SAndroid Build Coastguard Worker return true;
8795*8975f5c5SAndroid Build Coastguard Worker }
8796*8975f5c5SAndroid Build Coastguard Worker
ValidateSampleMaskiBase(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint maskNumber,GLbitfield mask)8797*8975f5c5SAndroid Build Coastguard Worker bool ValidateSampleMaskiBase(const PrivateState &state,
8798*8975f5c5SAndroid Build Coastguard Worker ErrorSet *errors,
8799*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8800*8975f5c5SAndroid Build Coastguard Worker GLuint maskNumber,
8801*8975f5c5SAndroid Build Coastguard Worker GLbitfield mask)
8802*8975f5c5SAndroid Build Coastguard Worker {
8803*8975f5c5SAndroid Build Coastguard Worker if (maskNumber >= static_cast<GLuint>(state.getCaps().maxSampleMaskWords))
8804*8975f5c5SAndroid Build Coastguard Worker {
8805*8975f5c5SAndroid Build Coastguard Worker errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSampleMaskNumber);
8806*8975f5c5SAndroid Build Coastguard Worker return false;
8807*8975f5c5SAndroid Build Coastguard Worker }
8808*8975f5c5SAndroid Build Coastguard Worker
8809*8975f5c5SAndroid Build Coastguard Worker return true;
8810*8975f5c5SAndroid Build Coastguard Worker }
8811*8975f5c5SAndroid Build Coastguard Worker
RecordDrawAttribsError(const Context * context,angle::EntryPoint entryPoint)8812*8975f5c5SAndroid Build Coastguard Worker void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint)
8813*8975f5c5SAndroid Build Coastguard Worker {
8814*8975f5c5SAndroid Build Coastguard Worker // An overflow can happen when adding the offset. Check against a special constant.
8815*8975f5c5SAndroid Build Coastguard Worker if (context->getStateCache().getNonInstancedVertexElementLimit() ==
8816*8975f5c5SAndroid Build Coastguard Worker VertexAttribute::kIntegerOverflow ||
8817*8975f5c5SAndroid Build Coastguard Worker context->getStateCache().getInstancedVertexElementLimit() ==
8818*8975f5c5SAndroid Build Coastguard Worker VertexAttribute::kIntegerOverflow)
8819*8975f5c5SAndroid Build Coastguard Worker {
8820*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
8821*8975f5c5SAndroid Build Coastguard Worker }
8822*8975f5c5SAndroid Build Coastguard Worker else
8823*8975f5c5SAndroid Build Coastguard Worker {
8824*8975f5c5SAndroid Build Coastguard Worker // [OpenGL ES 3.0.2] section 2.9.4 page 40:
8825*8975f5c5SAndroid Build Coastguard Worker // We can return INVALID_OPERATION if our buffer does not have enough backing data.
8826*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
8827*8975f5c5SAndroid Build Coastguard Worker }
8828*8975f5c5SAndroid Build Coastguard Worker }
8829*8975f5c5SAndroid Build Coastguard Worker
ValidateLoseContextCHROMIUM(const Context * context,angle::EntryPoint entryPoint,GraphicsResetStatus current,GraphicsResetStatus other)8830*8975f5c5SAndroid Build Coastguard Worker bool ValidateLoseContextCHROMIUM(const Context *context,
8831*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8832*8975f5c5SAndroid Build Coastguard Worker GraphicsResetStatus current,
8833*8975f5c5SAndroid Build Coastguard Worker GraphicsResetStatus other)
8834*8975f5c5SAndroid Build Coastguard Worker {
8835*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().loseContextCHROMIUM)
8836*8975f5c5SAndroid Build Coastguard Worker {
8837*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
8838*8975f5c5SAndroid Build Coastguard Worker return false;
8839*8975f5c5SAndroid Build Coastguard Worker }
8840*8975f5c5SAndroid Build Coastguard Worker
8841*8975f5c5SAndroid Build Coastguard Worker switch (current)
8842*8975f5c5SAndroid Build Coastguard Worker {
8843*8975f5c5SAndroid Build Coastguard Worker case GraphicsResetStatus::GuiltyContextReset:
8844*8975f5c5SAndroid Build Coastguard Worker case GraphicsResetStatus::InnocentContextReset:
8845*8975f5c5SAndroid Build Coastguard Worker case GraphicsResetStatus::UnknownContextReset:
8846*8975f5c5SAndroid Build Coastguard Worker break;
8847*8975f5c5SAndroid Build Coastguard Worker
8848*8975f5c5SAndroid Build Coastguard Worker default:
8849*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidResetStatus);
8850*8975f5c5SAndroid Build Coastguard Worker }
8851*8975f5c5SAndroid Build Coastguard Worker
8852*8975f5c5SAndroid Build Coastguard Worker switch (other)
8853*8975f5c5SAndroid Build Coastguard Worker {
8854*8975f5c5SAndroid Build Coastguard Worker case GraphicsResetStatus::GuiltyContextReset:
8855*8975f5c5SAndroid Build Coastguard Worker case GraphicsResetStatus::InnocentContextReset:
8856*8975f5c5SAndroid Build Coastguard Worker case GraphicsResetStatus::UnknownContextReset:
8857*8975f5c5SAndroid Build Coastguard Worker break;
8858*8975f5c5SAndroid Build Coastguard Worker
8859*8975f5c5SAndroid Build Coastguard Worker default:
8860*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidResetStatus);
8861*8975f5c5SAndroid Build Coastguard Worker }
8862*8975f5c5SAndroid Build Coastguard Worker
8863*8975f5c5SAndroid Build Coastguard Worker return true;
8864*8975f5c5SAndroid Build Coastguard Worker }
8865*8975f5c5SAndroid Build Coastguard Worker
8866*8975f5c5SAndroid Build Coastguard Worker // GL_ANGLE_texture_storage_external
ValidateTexImage2DExternalANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type)8867*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexImage2DExternalANGLE(const Context *context,
8868*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8869*8975f5c5SAndroid Build Coastguard Worker TextureTarget target,
8870*8975f5c5SAndroid Build Coastguard Worker GLint level,
8871*8975f5c5SAndroid Build Coastguard Worker GLint internalformat,
8872*8975f5c5SAndroid Build Coastguard Worker GLsizei width,
8873*8975f5c5SAndroid Build Coastguard Worker GLsizei height,
8874*8975f5c5SAndroid Build Coastguard Worker GLint border,
8875*8975f5c5SAndroid Build Coastguard Worker GLenum format,
8876*8975f5c5SAndroid Build Coastguard Worker GLenum type)
8877*8975f5c5SAndroid Build Coastguard Worker {
8878*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureExternalUpdateANGLE)
8879*8975f5c5SAndroid Build Coastguard Worker {
8880*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
8881*8975f5c5SAndroid Build Coastguard Worker return false;
8882*8975f5c5SAndroid Build Coastguard Worker }
8883*8975f5c5SAndroid Build Coastguard Worker
8884*8975f5c5SAndroid Build Coastguard Worker if (!ValidTexture2DDestinationTarget(context, target) &&
8885*8975f5c5SAndroid Build Coastguard Worker !ValidTextureExternalTarget(context, target))
8886*8975f5c5SAndroid Build Coastguard Worker {
8887*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
8888*8975f5c5SAndroid Build Coastguard Worker return false;
8889*8975f5c5SAndroid Build Coastguard Worker }
8890*8975f5c5SAndroid Build Coastguard Worker
8891*8975f5c5SAndroid Build Coastguard Worker if (context->getClientMajorVersion() <= 2)
8892*8975f5c5SAndroid Build Coastguard Worker {
8893*8975f5c5SAndroid Build Coastguard Worker if (!ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat,
8894*8975f5c5SAndroid Build Coastguard Worker false, false, 0, 0, width, height, border, format,
8895*8975f5c5SAndroid Build Coastguard Worker type, -1, nullptr))
8896*8975f5c5SAndroid Build Coastguard Worker {
8897*8975f5c5SAndroid Build Coastguard Worker return false;
8898*8975f5c5SAndroid Build Coastguard Worker }
8899*8975f5c5SAndroid Build Coastguard Worker }
8900*8975f5c5SAndroid Build Coastguard Worker else
8901*8975f5c5SAndroid Build Coastguard Worker {
8902*8975f5c5SAndroid Build Coastguard Worker if (!ValidateES3TexImageParametersBase(context, entryPoint, target, level, internalformat,
8903*8975f5c5SAndroid Build Coastguard Worker false, false, 0, 0, 0, width, height, 1, border,
8904*8975f5c5SAndroid Build Coastguard Worker format, type, -1, nullptr))
8905*8975f5c5SAndroid Build Coastguard Worker {
8906*8975f5c5SAndroid Build Coastguard Worker return false;
8907*8975f5c5SAndroid Build Coastguard Worker }
8908*8975f5c5SAndroid Build Coastguard Worker }
8909*8975f5c5SAndroid Build Coastguard Worker
8910*8975f5c5SAndroid Build Coastguard Worker return true;
8911*8975f5c5SAndroid Build Coastguard Worker }
8912*8975f5c5SAndroid Build Coastguard Worker
ValidateInvalidateTextureANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target)8913*8975f5c5SAndroid Build Coastguard Worker bool ValidateInvalidateTextureANGLE(const Context *context,
8914*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8915*8975f5c5SAndroid Build Coastguard Worker TextureType target)
8916*8975f5c5SAndroid Build Coastguard Worker {
8917*8975f5c5SAndroid Build Coastguard Worker if (!context->getExtensions().textureExternalUpdateANGLE)
8918*8975f5c5SAndroid Build Coastguard Worker {
8919*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
8920*8975f5c5SAndroid Build Coastguard Worker return false;
8921*8975f5c5SAndroid Build Coastguard Worker }
8922*8975f5c5SAndroid Build Coastguard Worker
8923*8975f5c5SAndroid Build Coastguard Worker if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
8924*8975f5c5SAndroid Build Coastguard Worker {
8925*8975f5c5SAndroid Build Coastguard Worker ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
8926*8975f5c5SAndroid Build Coastguard Worker return false;
8927*8975f5c5SAndroid Build Coastguard Worker }
8928*8975f5c5SAndroid Build Coastguard Worker
8929*8975f5c5SAndroid Build Coastguard Worker return true;
8930*8975f5c5SAndroid Build Coastguard Worker }
8931*8975f5c5SAndroid Build Coastguard Worker
ValidateProgramExecutableXFBBuffersPresent(const Context * context,const ProgramExecutable * programExecutable)8932*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
8933*8975f5c5SAndroid Build Coastguard Worker const ProgramExecutable *programExecutable)
8934*8975f5c5SAndroid Build Coastguard Worker {
8935*8975f5c5SAndroid Build Coastguard Worker size_t programXfbCount = programExecutable->getTransformFeedbackBufferCount();
8936*8975f5c5SAndroid Build Coastguard Worker const TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
8937*8975f5c5SAndroid Build Coastguard Worker for (size_t programXfbIndex = 0; programXfbIndex < programXfbCount; ++programXfbIndex)
8938*8975f5c5SAndroid Build Coastguard Worker {
8939*8975f5c5SAndroid Build Coastguard Worker const OffsetBindingPointer<Buffer> &buffer =
8940*8975f5c5SAndroid Build Coastguard Worker transformFeedback->getIndexedBuffer(programXfbIndex);
8941*8975f5c5SAndroid Build Coastguard Worker if (!buffer.get())
8942*8975f5c5SAndroid Build Coastguard Worker {
8943*8975f5c5SAndroid Build Coastguard Worker return false;
8944*8975f5c5SAndroid Build Coastguard Worker }
8945*8975f5c5SAndroid Build Coastguard Worker }
8946*8975f5c5SAndroid Build Coastguard Worker
8947*8975f5c5SAndroid Build Coastguard Worker return true;
8948*8975f5c5SAndroid Build Coastguard Worker }
8949*8975f5c5SAndroid Build Coastguard Worker
ValidateLogicOpCommon(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,LogicalOperation opcodePacked)8950*8975f5c5SAndroid Build Coastguard Worker bool ValidateLogicOpCommon(const PrivateState &state,
8951*8975f5c5SAndroid Build Coastguard Worker ErrorSet *errors,
8952*8975f5c5SAndroid Build Coastguard Worker angle::EntryPoint entryPoint,
8953*8975f5c5SAndroid Build Coastguard Worker LogicalOperation opcodePacked)
8954*8975f5c5SAndroid Build Coastguard Worker {
8955*8975f5c5SAndroid Build Coastguard Worker switch (opcodePacked)
8956*8975f5c5SAndroid Build Coastguard Worker {
8957*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::And:
8958*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::AndInverted:
8959*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::AndReverse:
8960*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Clear:
8961*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Copy:
8962*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::CopyInverted:
8963*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Equiv:
8964*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Invert:
8965*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Nand:
8966*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Noop:
8967*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Nor:
8968*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Or:
8969*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::OrInverted:
8970*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::OrReverse:
8971*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Set:
8972*8975f5c5SAndroid Build Coastguard Worker case LogicalOperation::Xor:
8973*8975f5c5SAndroid Build Coastguard Worker return true;
8974*8975f5c5SAndroid Build Coastguard Worker default:
8975*8975f5c5SAndroid Build Coastguard Worker errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLogicOp);
8976*8975f5c5SAndroid Build Coastguard Worker return false;
8977*8975f5c5SAndroid Build Coastguard Worker }
8978*8975f5c5SAndroid Build Coastguard Worker }
8979*8975f5c5SAndroid Build Coastguard Worker } // namespace gl
8980