1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // queryutils.cpp: Utilities for querying values from GL objects
8
9 #include "libANGLE/queryutils.h"
10
11 #include <algorithm>
12
13 #include "common/utilities.h"
14
15 #include "libANGLE/Buffer.h"
16 #include "libANGLE/Config.h"
17 #include "libANGLE/Context.h"
18 #include "libANGLE/Display.h"
19 #include "libANGLE/EGLSync.h"
20 #include "libANGLE/Fence.h"
21 #include "libANGLE/Framebuffer.h"
22 #include "libANGLE/GLES1State.h"
23 #include "libANGLE/MemoryObject.h"
24 #include "libANGLE/Program.h"
25 #include "libANGLE/Renderbuffer.h"
26 #include "libANGLE/Sampler.h"
27 #include "libANGLE/Shader.h"
28 #include "libANGLE/Surface.h"
29 #include "libANGLE/Texture.h"
30 #include "libANGLE/Uniform.h"
31 #include "libANGLE/VertexAttribute.h"
32 #include "libANGLE/queryconversions.h"
33
34 namespace gl
35 {
36
37 namespace
38 {
39
40 template <bool isPureInteger>
ConvertToColor(const GLfloat * params)41 ColorGeneric ConvertToColor(const GLfloat *params)
42 {
43 if (isPureInteger)
44 {
45 UNREACHABLE();
46 return ColorGeneric(ColorI());
47 }
48 else
49 {
50 return ColorGeneric(ColorF::fromData(params));
51 }
52 }
53
54 template <bool isPureInteger>
ConvertToColor(const GLint * params)55 ColorGeneric ConvertToColor(const GLint *params)
56 {
57 if (isPureInteger)
58 {
59 return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
60 }
61 else
62 {
63 return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
64 normalizedToFloat(params[2]), normalizedToFloat(params[3])));
65 }
66 }
67
68 template <bool isPureInteger>
ConvertToColor(const GLuint * params)69 ColorGeneric ConvertToColor(const GLuint *params)
70 {
71 if (isPureInteger)
72 {
73 return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
74 }
75 else
76 {
77 UNREACHABLE();
78 return ColorGeneric(ColorF());
79 }
80 }
81
82 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLfloat * outParams)83 void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
84 {
85 if (isPureInteger)
86 {
87 UNREACHABLE();
88 }
89 else
90 {
91 color.colorF.writeData(outParams);
92 }
93 }
94
95 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLint * outParams)96 void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
97 {
98 if (isPureInteger)
99 {
100 outParams[0] = color.colorI.red;
101 outParams[1] = color.colorI.green;
102 outParams[2] = color.colorI.blue;
103 outParams[3] = color.colorI.alpha;
104 }
105 else
106 {
107 outParams[0] = floatToNormalized<GLint>(color.colorF.red);
108 outParams[1] = floatToNormalized<GLint>(color.colorF.green);
109 outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
110 outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
111 }
112 }
113
114 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLuint * outParams)115 void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
116 {
117 if (isPureInteger)
118 {
119 constexpr unsigned int kMinValue = 0;
120
121 outParams[0] = std::max(color.colorUI.red, kMinValue);
122 outParams[1] = std::max(color.colorUI.green, kMinValue);
123 outParams[2] = std::max(color.colorUI.blue, kMinValue);
124 outParams[3] = std::max(color.colorUI.alpha, kMinValue);
125 }
126 else
127 {
128 UNREACHABLE();
129 }
130 }
131
132 template <typename ParamType>
QueryTexLevelParameterBase(const Texture * texture,TextureTarget target,GLint level,GLenum pname,ParamType * params)133 void QueryTexLevelParameterBase(const Texture *texture,
134 TextureTarget target,
135 GLint level,
136 GLenum pname,
137 ParamType *params)
138 {
139 ASSERT(texture != nullptr);
140 const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
141
142 switch (pname)
143 {
144 case GL_TEXTURE_RED_TYPE:
145 *params = CastFromGLintStateValue<ParamType>(
146 pname, info->redBits ? info->componentType : GL_NONE);
147 break;
148 case GL_TEXTURE_GREEN_TYPE:
149 *params = CastFromGLintStateValue<ParamType>(
150 pname, info->greenBits ? info->componentType : GL_NONE);
151 break;
152 case GL_TEXTURE_BLUE_TYPE:
153 *params = CastFromGLintStateValue<ParamType>(
154 pname, info->blueBits ? info->componentType : GL_NONE);
155 break;
156 case GL_TEXTURE_ALPHA_TYPE:
157 *params = CastFromGLintStateValue<ParamType>(
158 pname, info->alphaBits ? info->componentType : GL_NONE);
159 break;
160 case GL_TEXTURE_DEPTH_TYPE:
161 *params = CastFromGLintStateValue<ParamType>(
162 pname, info->depthBits ? info->componentType : GL_NONE);
163 break;
164 case GL_TEXTURE_RED_SIZE:
165 *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
166 break;
167 case GL_TEXTURE_GREEN_SIZE:
168 *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
169 break;
170 case GL_TEXTURE_BLUE_SIZE:
171 *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
172 break;
173 case GL_TEXTURE_ALPHA_SIZE:
174 *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
175 break;
176 case GL_TEXTURE_DEPTH_SIZE:
177 *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
178 break;
179 case GL_TEXTURE_STENCIL_SIZE:
180 *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
181 break;
182 case GL_TEXTURE_SHARED_SIZE:
183 *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
184 break;
185 case GL_TEXTURE_INTERNAL_FORMAT:
186 *params = CastFromGLintStateValue<ParamType>(
187 pname, info->internalFormat ? info->internalFormat : GL_RGBA);
188 break;
189 case GL_TEXTURE_WIDTH:
190 *params = CastFromGLintStateValue<ParamType>(
191 pname, static_cast<uint32_t>(texture->getWidth(target, level)));
192 break;
193 case GL_TEXTURE_HEIGHT:
194 *params = CastFromGLintStateValue<ParamType>(
195 pname, static_cast<uint32_t>(texture->getHeight(target, level)));
196 break;
197 case GL_TEXTURE_DEPTH:
198 *params = CastFromGLintStateValue<ParamType>(
199 pname, static_cast<uint32_t>(texture->getDepth(target, level)));
200 break;
201 case GL_TEXTURE_SAMPLES:
202 *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
203 break;
204 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
205 *params = CastFromStateValue<ParamType>(
206 pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
207 break;
208 case GL_TEXTURE_COMPRESSED:
209 *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
210 break;
211 case GL_MEMORY_SIZE_ANGLE:
212 *params =
213 CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
214 break;
215 case GL_RESOURCE_INITIALIZED_ANGLE:
216 *params = CastFromGLintStateValue<ParamType>(
217 pname, texture->initState(GL_NONE, ImageIndex::MakeFromTarget(target, level)) ==
218 InitState::Initialized);
219 break;
220 case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
221 *params = CastFromStateValue<ParamType>(
222 pname, static_cast<GLint>(texture->getBuffer().id().value));
223 break;
224 case GL_TEXTURE_BUFFER_OFFSET:
225 *params = CastFromStateValue<ParamType>(
226 pname, static_cast<GLint>(texture->getBuffer().getOffset()));
227 break;
228 case GL_TEXTURE_BUFFER_SIZE:
229 *params = CastFromStateValue<ParamType>(
230 pname, static_cast<GLint>(GetBoundBufferAvailableSize(texture->getBuffer())));
231 break;
232 default:
233 UNREACHABLE();
234 break;
235 }
236 }
237
238 // This function is needed to handle fixed_point data.
239 // It can be used when some pname need special conversion from int/float/bool to fixed_point.
240 template <bool isGLfixed, typename QueryT, typename ParamType>
CastFromSpecialValue(GLenum pname,const ParamType param)241 QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
242 {
243 if (isGLfixed)
244 {
245 return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
246 }
247 else
248 {
249 return CastFromStateValue<QueryT>(pname, param);
250 }
251 }
252
253 template <bool isPureInteger, bool isGLfixed, typename ParamType>
QueryTexParameterBase(const Context * context,const Texture * texture,GLenum pname,ParamType * params)254 void QueryTexParameterBase(const Context *context,
255 const Texture *texture,
256 GLenum pname,
257 ParamType *params)
258 {
259 ASSERT(texture != nullptr);
260
261 switch (pname)
262 {
263 case GL_TEXTURE_MAG_FILTER:
264 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
265 break;
266 case GL_TEXTURE_MIN_FILTER:
267 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
268 break;
269 case GL_TEXTURE_WRAP_S:
270 *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
271 break;
272 case GL_TEXTURE_WRAP_T:
273 *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
274 break;
275 case GL_TEXTURE_WRAP_R:
276 *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
277 break;
278 case GL_TEXTURE_IMMUTABLE_FORMAT:
279 *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
280 break;
281 case GL_TEXTURE_IMMUTABLE_LEVELS:
282 *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
283 break;
284 case GL_TEXTURE_USAGE_ANGLE:
285 *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
286 break;
287 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
288 *params =
289 CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
290 break;
291 case GL_TEXTURE_SWIZZLE_R:
292 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
293 break;
294 case GL_TEXTURE_SWIZZLE_G:
295 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
296 break;
297 case GL_TEXTURE_SWIZZLE_B:
298 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
299 break;
300 case GL_TEXTURE_SWIZZLE_A:
301 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
302 break;
303 case GL_TEXTURE_BASE_LEVEL:
304 *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
305 break;
306 case GL_TEXTURE_MAX_LEVEL:
307 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
308 break;
309 case GL_TEXTURE_MIN_LOD:
310 *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
311 break;
312 case GL_TEXTURE_MAX_LOD:
313 *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
314 break;
315 case GL_TEXTURE_COMPARE_MODE:
316 *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
317 break;
318 case GL_TEXTURE_COMPARE_FUNC:
319 *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
320 break;
321 case GL_TEXTURE_SRGB_DECODE_EXT:
322 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
323 break;
324 case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
325 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBOverride());
326 break;
327 case GL_DEPTH_STENCIL_TEXTURE_MODE:
328 *params =
329 CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
330 break;
331 case GL_TEXTURE_CROP_RECT_OES:
332 {
333 const gl::Rectangle &crop = texture->getCrop();
334 params[0] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
335 params[1] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
336 params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
337 params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
338 break;
339 }
340 case GL_GENERATE_MIPMAP:
341 *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
342 break;
343 case GL_MEMORY_SIZE_ANGLE:
344 *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
345 break;
346 case GL_TEXTURE_BORDER_COLOR:
347 ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
348 break;
349 case GL_TEXTURE_NATIVE_ID_ANGLE:
350 *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
351 break;
352 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
353 *params = CastFromGLintStateValue<ParamType>(
354 pname, texture->getImplementationColorReadFormat(context));
355 break;
356 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
357 *params = CastFromGLintStateValue<ParamType>(
358 pname, texture->getImplementationColorReadType(context));
359 break;
360 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
361 *params =
362 CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
363 break;
364 case GL_RESOURCE_INITIALIZED_ANGLE:
365 *params = CastFromGLintStateValue<ParamType>(
366 pname, texture->initState() == InitState::Initialized);
367 break;
368 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
369 *params = CastFromGLintStateValue<ParamType>(
370 pname, texture->getRequiredTextureImageUnits(context));
371 break;
372 case GL_TEXTURE_PROTECTED_EXT:
373 *params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
374 break;
375 case GL_TEXTURE_TILING_EXT:
376 *params = CastFromGLintStateValue<ParamType>(pname, texture->getTilingMode());
377 break;
378 case GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM:
379 *params = CastFromGLintStateValue<ParamType>(pname, texture->getFoveatedFeatureBits());
380 break;
381 case GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM:
382 *params =
383 CastFromGLintStateValue<ParamType>(pname, texture->getSupportedFoveationFeatures());
384 break;
385 case GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM:
386 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinPixelDensity());
387 break;
388 case GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM:
389 *params = CastFromGLintStateValue<ParamType>(pname, texture->getNumFocalPoints());
390 break;
391 default:
392 UNREACHABLE();
393 break;
394 }
395 }
396
397 // this function is needed to handle OES_FIXED_POINT.
398 // Some pname values can take in GLfixed values and may need to be converted
399 template <bool isGLfixed, typename ReturnType, typename ParamType>
ConvertTexParam(GLenum pname,const ParamType param)400 ReturnType ConvertTexParam(GLenum pname, const ParamType param)
401 {
402 if (isGLfixed)
403 {
404 return CastQueryValueTo<ReturnType>(pname,
405 ConvertFixedToFloat(static_cast<GLfixed>(param)));
406 }
407 else
408 {
409 return CastQueryValueTo<ReturnType>(pname, param);
410 }
411 }
412
413 template <bool isPureInteger, bool isGLfixed, typename ParamType>
SetTexParameterBase(Context * context,Texture * texture,GLenum pname,const ParamType * params)414 void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
415 {
416 ASSERT(texture != nullptr);
417
418 switch (pname)
419 {
420 case GL_TEXTURE_WRAP_S:
421 texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
422 break;
423 case GL_TEXTURE_WRAP_T:
424 texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
425 break;
426 case GL_TEXTURE_WRAP_R:
427 texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
428 break;
429 case GL_TEXTURE_MIN_FILTER:
430 texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
431 break;
432 case GL_TEXTURE_MAG_FILTER:
433 texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
434 break;
435 case GL_TEXTURE_USAGE_ANGLE:
436 texture->setUsage(context, ConvertToGLenum(pname, params[0]));
437 break;
438 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
439 texture->setMaxAnisotropy(context,
440 ConvertTexParam<isGLfixed, GLfloat>(pname, params[0]));
441 break;
442 case GL_TEXTURE_COMPARE_MODE:
443 texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
444 break;
445 case GL_TEXTURE_COMPARE_FUNC:
446 texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
447 break;
448 case GL_TEXTURE_SWIZZLE_R:
449 texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
450 break;
451 case GL_TEXTURE_SWIZZLE_G:
452 texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
453 break;
454 case GL_TEXTURE_SWIZZLE_B:
455 texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
456 break;
457 case GL_TEXTURE_SWIZZLE_A:
458 texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
459 break;
460 case GL_TEXTURE_BASE_LEVEL:
461 {
462 (void)(texture->setBaseLevel(
463 context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
464 break;
465 }
466 case GL_TEXTURE_MAX_LEVEL:
467 texture->setMaxLevel(context,
468 clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
469 break;
470 case GL_TEXTURE_MIN_LOD:
471 texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
472 break;
473 case GL_TEXTURE_MAX_LOD:
474 texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
475 break;
476 case GL_DEPTH_STENCIL_TEXTURE_MODE:
477 texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
478 break;
479 case GL_TEXTURE_SRGB_DECODE_EXT:
480 texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
481 break;
482 case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
483 texture->setSRGBOverride(context, ConvertToGLenum(pname, params[0]));
484 break;
485 case GL_TEXTURE_CROP_RECT_OES:
486 texture->setCrop(gl::Rectangle(ConvertTexParam<isGLfixed, GLint>(pname, params[0]),
487 ConvertTexParam<isGLfixed, GLint>(pname, params[1]),
488 ConvertTexParam<isGLfixed, GLint>(pname, params[2]),
489 ConvertTexParam<isGLfixed, GLint>(pname, params[3])));
490 break;
491 case GL_GENERATE_MIPMAP:
492 texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
493 break;
494 case GL_TEXTURE_BORDER_COLOR:
495 texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
496 break;
497 case GL_RESOURCE_INITIALIZED_ANGLE:
498 texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
499 : InitState::MayNeedInit);
500 break;
501 case GL_TEXTURE_PROTECTED_EXT:
502 texture->setProtectedContent(context, (params[0] == GL_TRUE));
503 break;
504 case GL_RENDERABILITY_VALIDATION_ANGLE:
505 texture->setRenderabilityValidation(context, (params[0] == GL_TRUE));
506 break;
507 case GL_TEXTURE_TILING_EXT:
508 texture->setTilingMode(context, ConvertToGLenum(pname, params[0]));
509 break;
510 case GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM:
511 texture->setFoveatedFeatureBits(ConvertToGLenum(pname, params[0]));
512 break;
513 case GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM:
514 texture->setMinPixelDensity(ConvertToGLfloat(params[0]));
515 break;
516 default:
517 UNREACHABLE();
518 break;
519 }
520 }
521
522 template <bool isPureInteger, typename ParamType>
QuerySamplerParameterBase(const Sampler * sampler,GLenum pname,ParamType * params)523 void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
524 {
525 switch (pname)
526 {
527 case GL_TEXTURE_MIN_FILTER:
528 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
529 break;
530 case GL_TEXTURE_MAG_FILTER:
531 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
532 break;
533 case GL_TEXTURE_WRAP_S:
534 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
535 break;
536 case GL_TEXTURE_WRAP_T:
537 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
538 break;
539 case GL_TEXTURE_WRAP_R:
540 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
541 break;
542 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
543 *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
544 break;
545 case GL_TEXTURE_MIN_LOD:
546 *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
547 break;
548 case GL_TEXTURE_MAX_LOD:
549 *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
550 break;
551 case GL_TEXTURE_COMPARE_MODE:
552 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
553 break;
554 case GL_TEXTURE_COMPARE_FUNC:
555 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
556 break;
557 case GL_TEXTURE_SRGB_DECODE_EXT:
558 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
559 break;
560 case GL_TEXTURE_BORDER_COLOR:
561 ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
562 break;
563 default:
564 UNREACHABLE();
565 break;
566 }
567 }
568
569 template <bool isPureInteger, typename ParamType>
SetSamplerParameterBase(Context * context,Sampler * sampler,GLenum pname,const ParamType * params)570 void SetSamplerParameterBase(Context *context,
571 Sampler *sampler,
572 GLenum pname,
573 const ParamType *params)
574 {
575 switch (pname)
576 {
577 case GL_TEXTURE_WRAP_S:
578 sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
579 break;
580 case GL_TEXTURE_WRAP_T:
581 sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
582 break;
583 case GL_TEXTURE_WRAP_R:
584 sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
585 break;
586 case GL_TEXTURE_MIN_FILTER:
587 sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
588 break;
589 case GL_TEXTURE_MAG_FILTER:
590 sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
591 break;
592 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
593 sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
594 break;
595 case GL_TEXTURE_COMPARE_MODE:
596 sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
597 break;
598 case GL_TEXTURE_COMPARE_FUNC:
599 sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
600 break;
601 case GL_TEXTURE_MIN_LOD:
602 sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
603 break;
604 case GL_TEXTURE_MAX_LOD:
605 sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
606 break;
607 case GL_TEXTURE_SRGB_DECODE_EXT:
608 sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
609 break;
610 case GL_TEXTURE_BORDER_COLOR:
611 sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
612 break;
613 default:
614 UNREACHABLE();
615 break;
616 }
617
618 sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
619 }
620
621 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
622 template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
QueryVertexAttribBase(const VertexAttribute & attrib,const VertexBinding & binding,const CurrentDataType (& currentValueData)[CurrentValueCount],GLenum pname,ParamType * params)623 void QueryVertexAttribBase(const VertexAttribute &attrib,
624 const VertexBinding &binding,
625 const CurrentDataType (¤tValueData)[CurrentValueCount],
626 GLenum pname,
627 ParamType *params)
628 {
629 switch (pname)
630 {
631 case GL_CURRENT_VERTEX_ATTRIB:
632 for (size_t i = 0; i < CurrentValueCount; ++i)
633 {
634 params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
635 }
636 break;
637 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
638 *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
639 break;
640 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
641 *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
642 break;
643 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
644 *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
645 break;
646 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
647 *params = CastFromGLintStateValue<ParamType>(
648 pname, gl::ToGLenum(attrib.format->vertexAttribType));
649 break;
650 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
651 *params =
652 CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
653 break;
654 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
655 *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id().value);
656 break;
657 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
658 *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
659 break;
660 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
661 *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
662 break;
663 case GL_VERTEX_ATTRIB_BINDING:
664 *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
665 break;
666 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
667 *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
668 break;
669 default:
670 UNREACHABLE();
671 break;
672 }
673 }
674
675 template <typename ParamType>
QueryBufferParameterBase(const Buffer * buffer,GLenum pname,ParamType * params)676 void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
677 {
678 ASSERT(buffer != nullptr);
679
680 switch (pname)
681 {
682 case GL_BUFFER_USAGE:
683 *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
684 break;
685 case GL_BUFFER_SIZE:
686 *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
687 break;
688 case GL_BUFFER_ACCESS_FLAGS:
689 *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
690 break;
691 case GL_BUFFER_ACCESS_OES:
692 *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
693 break;
694 case GL_BUFFER_MAPPED:
695 *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
696 break;
697 case GL_BUFFER_MAP_OFFSET:
698 *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
699 break;
700 case GL_BUFFER_MAP_LENGTH:
701 *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
702 break;
703 case GL_MEMORY_SIZE_ANGLE:
704 *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
705 break;
706 case GL_BUFFER_IMMUTABLE_STORAGE_EXT:
707 *params = CastFromStateValue<ParamType>(pname, buffer->isImmutable());
708 break;
709 case GL_BUFFER_STORAGE_FLAGS_EXT:
710 *params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags());
711 break;
712 case GL_RESOURCE_INITIALIZED_ANGLE:
713 *params = CastFromStateValue<ParamType>(
714 pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized));
715 break;
716 default:
717 UNREACHABLE();
718 break;
719 }
720 }
721
722 template <typename T>
GetCommonVariableProperty(const T & var,GLenum prop)723 GLint GetCommonVariableProperty(const T &var, GLenum prop)
724 {
725 switch (prop)
726 {
727 case GL_TYPE:
728 return clampCast<GLint>(var.pod.type);
729
730 case GL_ARRAY_SIZE:
731 // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
732 // see GLES 3.1 spec section 7.3.1.1 page 77.
733 return clampCast<GLint>(var.getBasicTypeElementCount());
734
735 case GL_NAME_LENGTH:
736 // ES31 spec p84: This counts the terminating null char.
737 return clampCast<GLint>(var.name.size() + 1u);
738
739 default:
740 UNREACHABLE();
741 return GL_INVALID_VALUE;
742 }
743 }
744
GetInputResourceProperty(const Program * program,GLuint index,GLenum prop)745 GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
746 {
747 const ProgramExecutable &executable = program->getExecutable();
748 const ProgramInput &variable = executable.getInputResource(index);
749
750 switch (prop)
751 {
752 case GL_TYPE:
753 return clampCast<GLint>(variable.getType());
754 case GL_ARRAY_SIZE:
755 return clampCast<GLint>(variable.getBasicTypeElementCount());
756
757 case GL_NAME_LENGTH:
758 return clampCast<GLint>(executable.getInputResourceName(index).size() + 1u);
759
760 case GL_LOCATION:
761 return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.getLocation();
762
763 // The query is targeted at the set of active input variables used by the first shader stage
764 // of program. If program contains multiple shader stages then input variables from any
765 // stage other than the first will not be enumerated. Since we found the variable to get
766 // this far, we know it exists in the first attached shader stage.
767 case GL_REFERENCED_BY_VERTEX_SHADER:
768 return executable.getFirstLinkedShaderStageType() == ShaderType::Vertex;
769 case GL_REFERENCED_BY_FRAGMENT_SHADER:
770 return executable.getFirstLinkedShaderStageType() == ShaderType::Fragment;
771 case GL_REFERENCED_BY_COMPUTE_SHADER:
772 return executable.getFirstLinkedShaderStageType() == ShaderType::Compute;
773 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
774 return executable.getFirstLinkedShaderStageType() == ShaderType::Geometry;
775 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
776 return executable.getFirstLinkedShaderStageType() == ShaderType::TessControl;
777 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
778 return executable.getFirstLinkedShaderStageType() == ShaderType::TessEvaluation;
779 case GL_IS_PER_PATCH_EXT:
780 return variable.isPatch();
781
782 default:
783 UNREACHABLE();
784 return GL_INVALID_VALUE;
785 }
786 }
787
GetOutputResourceProperty(const Program * program,GLuint index,const GLenum prop)788 GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
789 {
790 const ProgramExecutable &executable = program->getExecutable();
791 const ProgramOutput &outputVariable = executable.getOutputResource(index);
792
793 switch (prop)
794 {
795 case GL_TYPE:
796 return clampCast<GLint>(outputVariable.pod.type);
797 case GL_ARRAY_SIZE:
798 return clampCast<GLint>(outputVariable.pod.basicTypeElementCount);
799
800 case GL_NAME_LENGTH:
801 return clampCast<GLint>(executable.getOutputResourceName(index).size() + 1u);
802
803 case GL_LOCATION:
804 return outputVariable.pod.location;
805
806 case GL_LOCATION_INDEX_EXT:
807 // EXT_blend_func_extended
808 if (executable.getLastLinkedShaderStageType() == gl::ShaderType::Fragment)
809 {
810 return executable.getFragDataIndex(outputVariable.name);
811 }
812 return GL_INVALID_INDEX;
813
814 // The set of active user-defined outputs from the final shader stage in this program. If
815 // the final stage is a Fragment Shader, then this represents the fragment outputs that get
816 // written to individual color buffers. If the program only contains a Compute Shader, then
817 // there are no user-defined outputs.
818 case GL_REFERENCED_BY_VERTEX_SHADER:
819 return executable.getLastLinkedShaderStageType() == ShaderType::Vertex;
820 case GL_REFERENCED_BY_FRAGMENT_SHADER:
821 return executable.getLastLinkedShaderStageType() == ShaderType::Fragment;
822 case GL_REFERENCED_BY_COMPUTE_SHADER:
823 return executable.getLastLinkedShaderStageType() == ShaderType::Compute;
824 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
825 return executable.getLastLinkedShaderStageType() == ShaderType::Geometry;
826 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
827 return executable.getLastLinkedShaderStageType() == ShaderType::TessControl;
828 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
829 return executable.getLastLinkedShaderStageType() == ShaderType::TessEvaluation;
830 case GL_IS_PER_PATCH_EXT:
831 return outputVariable.pod.isPatch;
832
833 default:
834 UNREACHABLE();
835 return GL_INVALID_VALUE;
836 }
837 }
838
GetTransformFeedbackVaryingResourceProperty(const Program * program,GLuint index,const GLenum prop)839 GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
840 GLuint index,
841 const GLenum prop)
842 {
843 const ProgramExecutable &executable = program->getExecutable();
844 const TransformFeedbackVarying &tfVariable =
845 executable.getTransformFeedbackVaryingResource(index);
846 switch (prop)
847 {
848 case GL_TYPE:
849 return clampCast<GLint>(tfVariable.type);
850
851 case GL_ARRAY_SIZE:
852 return clampCast<GLint>(tfVariable.size());
853
854 case GL_NAME_LENGTH:
855 return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
856
857 default:
858 UNREACHABLE();
859 return GL_INVALID_VALUE;
860 }
861 }
862
QueryProgramInterfaceActiveResources(const Program * program,GLenum programInterface)863 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
864 {
865 const ProgramExecutable &executable = program->getExecutable();
866 switch (programInterface)
867 {
868 case GL_PROGRAM_INPUT:
869 return clampCast<GLint>(executable.getProgramInputs().size());
870
871 case GL_PROGRAM_OUTPUT:
872 return clampCast<GLint>(executable.getOutputVariables().size());
873
874 case GL_UNIFORM:
875 return clampCast<GLint>(executable.getUniforms().size());
876
877 case GL_UNIFORM_BLOCK:
878 return clampCast<GLint>(executable.getUniformBlocks().size());
879
880 case GL_ATOMIC_COUNTER_BUFFER:
881 return clampCast<GLint>(executable.getAtomicCounterBuffers().size());
882
883 case GL_BUFFER_VARIABLE:
884 return clampCast<GLint>(executable.getBufferVariables().size());
885
886 case GL_SHADER_STORAGE_BLOCK:
887 return clampCast<GLint>(executable.getShaderStorageBlocks().size());
888
889 case GL_TRANSFORM_FEEDBACK_VARYING:
890 return clampCast<GLint>(executable.getLinkedTransformFeedbackVaryings().size());
891
892 default:
893 UNREACHABLE();
894 return 0;
895 }
896 }
897
898 template <typename T, typename M>
FindMaxSize(const std::vector<T> & resources,M member)899 GLint FindMaxSize(const std::vector<T> &resources, M member)
900 {
901 GLint max = 0;
902 for (const T &resource : resources)
903 {
904 max = std::max(max, clampCast<GLint>((resource.*member).size()));
905 }
906 return max;
907 }
908
FindMaxNameLength(const std::vector<std::string> & names)909 GLint FindMaxNameLength(const std::vector<std::string> &names)
910 {
911 GLint max = 0;
912 for (const std::string &name : names)
913 {
914 max = std::max(max, clampCast<GLint>(name.size()));
915 }
916 return max;
917 }
918
QueryProgramInterfaceMaxNameLength(const Program * program,GLenum programInterface)919 GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
920 {
921 const ProgramExecutable &executable = program->getExecutable();
922
923 GLint maxNameLength = 0;
924 switch (programInterface)
925 {
926 case GL_PROGRAM_INPUT:
927 maxNameLength = executable.getInputResourceMaxNameSize();
928 break;
929
930 case GL_PROGRAM_OUTPUT:
931 maxNameLength = executable.getOutputResourceMaxNameSize();
932 break;
933
934 case GL_UNIFORM:
935 maxNameLength = FindMaxNameLength(executable.getUniformNames());
936 break;
937
938 case GL_UNIFORM_BLOCK:
939 return executable.getActiveUniformBlockMaxNameLength();
940
941 case GL_BUFFER_VARIABLE:
942 maxNameLength = FindMaxSize(executable.getBufferVariables(), &BufferVariable::name);
943 break;
944
945 case GL_SHADER_STORAGE_BLOCK:
946 return executable.getActiveShaderStorageBlockMaxNameLength();
947
948 case GL_TRANSFORM_FEEDBACK_VARYING:
949 return clampCast<GLint>(executable.getTransformFeedbackVaryingMaxLength());
950
951 default:
952 UNREACHABLE();
953 return 0;
954 }
955 // This length includes an extra character for the null terminator.
956 return (maxNameLength == 0 ? 0 : maxNameLength + 1);
957 }
958
QueryProgramInterfaceMaxNumActiveVariables(const Program * program,GLenum programInterface)959 GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
960 {
961 const ProgramExecutable &executable = program->getExecutable();
962
963 switch (programInterface)
964 {
965 case GL_UNIFORM_BLOCK:
966 return FindMaxSize(executable.getUniformBlocks(), &InterfaceBlock::memberIndexes);
967 case GL_ATOMIC_COUNTER_BUFFER:
968 return FindMaxSize(executable.getAtomicCounterBuffers(),
969 &AtomicCounterBuffer::memberIndexes);
970
971 case GL_SHADER_STORAGE_BLOCK:
972 return FindMaxSize(executable.getShaderStorageBlocks(), &InterfaceBlock::memberIndexes);
973
974 default:
975 UNREACHABLE();
976 return 0;
977 }
978 }
979
GetUniformPropertyEnum(GLenum prop)980 GLenum GetUniformPropertyEnum(GLenum prop)
981 {
982 switch (prop)
983 {
984 case GL_UNIFORM_TYPE:
985 return GL_TYPE;
986 case GL_UNIFORM_SIZE:
987 return GL_ARRAY_SIZE;
988 case GL_UNIFORM_NAME_LENGTH:
989 return GL_NAME_LENGTH;
990 case GL_UNIFORM_BLOCK_INDEX:
991 return GL_BLOCK_INDEX;
992 case GL_UNIFORM_OFFSET:
993 return GL_OFFSET;
994 case GL_UNIFORM_ARRAY_STRIDE:
995 return GL_ARRAY_STRIDE;
996 case GL_UNIFORM_MATRIX_STRIDE:
997 return GL_MATRIX_STRIDE;
998 case GL_UNIFORM_IS_ROW_MAJOR:
999 return GL_IS_ROW_MAJOR;
1000
1001 default:
1002 return prop;
1003 }
1004 }
1005
GetUniformBlockPropertyEnum(GLenum prop)1006 GLenum GetUniformBlockPropertyEnum(GLenum prop)
1007 {
1008 switch (prop)
1009 {
1010 case GL_UNIFORM_BLOCK_BINDING:
1011 return GL_BUFFER_BINDING;
1012
1013 case GL_UNIFORM_BLOCK_DATA_SIZE:
1014 return GL_BUFFER_DATA_SIZE;
1015
1016 case GL_UNIFORM_BLOCK_NAME_LENGTH:
1017 return GL_NAME_LENGTH;
1018
1019 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
1020 return GL_NUM_ACTIVE_VARIABLES;
1021
1022 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
1023 return GL_ACTIVE_VARIABLES;
1024
1025 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
1026 return GL_REFERENCED_BY_VERTEX_SHADER;
1027
1028 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
1029 return GL_REFERENCED_BY_FRAGMENT_SHADER;
1030
1031 default:
1032 return prop;
1033 }
1034 }
1035
1036 template <typename ShaderVariableT>
GetShaderVariableBufferResourceProperty(const ShaderVariableT & buffer,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1037 void GetShaderVariableBufferResourceProperty(const ShaderVariableT &buffer,
1038 GLenum pname,
1039 GLint *params,
1040 GLsizei bufSize,
1041 GLsizei *outputPosition)
1042
1043 {
1044 switch (pname)
1045 {
1046 case GL_BUFFER_DATA_SIZE:
1047 params[(*outputPosition)++] = clampCast<GLint>(buffer.pod.dataSize);
1048 break;
1049 case GL_NUM_ACTIVE_VARIABLES:
1050 params[(*outputPosition)++] = buffer.numActiveVariables();
1051 break;
1052 case GL_ACTIVE_VARIABLES:
1053 for (size_t memberIndex = 0;
1054 memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
1055 ++memberIndex)
1056 {
1057 params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
1058 }
1059 break;
1060 case GL_REFERENCED_BY_VERTEX_SHADER:
1061 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
1062 break;
1063 case GL_REFERENCED_BY_FRAGMENT_SHADER:
1064 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
1065 break;
1066 case GL_REFERENCED_BY_COMPUTE_SHADER:
1067 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
1068 break;
1069 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1070 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
1071 break;
1072 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
1073 params[(*outputPosition)++] =
1074 static_cast<GLint>(buffer.isActive(ShaderType::TessControl));
1075 break;
1076 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
1077 params[(*outputPosition)++] =
1078 static_cast<GLint>(buffer.isActive(ShaderType::TessEvaluation));
1079 break;
1080 default:
1081 UNREACHABLE();
1082 break;
1083 }
1084 }
1085
GetInterfaceBlockResourceProperty(const InterfaceBlock & block,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1086 void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
1087 GLenum pname,
1088 GLint *params,
1089 GLsizei bufSize,
1090 GLsizei *outputPosition)
1091 {
1092 if (pname == GL_NAME_LENGTH)
1093 {
1094 params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
1095 return;
1096 }
1097 GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
1098 }
1099
GetUniformBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1100 void GetUniformBlockResourceProperty(const Program *program,
1101 GLuint blockIndex,
1102 GLenum pname,
1103 GLint *params,
1104 GLsizei bufSize,
1105 GLsizei *outputPosition)
1106
1107 {
1108 ASSERT(*outputPosition < bufSize);
1109
1110 if (pname == GL_BUFFER_BINDING)
1111 {
1112 params[(*outputPosition)++] = program->getExecutable().getUniformBlockBinding(blockIndex);
1113 return;
1114 }
1115
1116 const auto &block = program->getExecutable().getUniformBlockByIndex(blockIndex);
1117 GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
1118 }
1119
GetShaderStorageBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1120 void GetShaderStorageBlockResourceProperty(const Program *program,
1121 GLuint blockIndex,
1122 GLenum pname,
1123 GLint *params,
1124 GLsizei bufSize,
1125 GLsizei *outputPosition)
1126
1127 {
1128 ASSERT(*outputPosition < bufSize);
1129
1130 if (pname == GL_BUFFER_BINDING)
1131 {
1132 params[(*outputPosition)++] =
1133 program->getExecutable().getShaderStorageBlockBinding(blockIndex);
1134 return;
1135 }
1136
1137 const auto &block = program->getExecutable().getShaderStorageBlockByIndex(blockIndex);
1138 GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
1139 }
1140
GetAtomicCounterBufferResourceProperty(const Program * program,GLuint index,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1141 void GetAtomicCounterBufferResourceProperty(const Program *program,
1142 GLuint index,
1143 GLenum pname,
1144 GLint *params,
1145 GLsizei bufSize,
1146 GLsizei *outputPosition)
1147
1148 {
1149 ASSERT(*outputPosition < bufSize);
1150
1151 if (pname == GL_BUFFER_BINDING)
1152 {
1153 params[(*outputPosition)++] = program->getExecutable().getAtomicCounterBufferBinding(index);
1154 return;
1155 }
1156
1157 const auto &buffer = program->getExecutable().getAtomicCounterBuffers()[index];
1158 GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
1159 }
1160
IsTextureEnvEnumParameter(TextureEnvParameter pname)1161 bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
1162 {
1163 switch (pname)
1164 {
1165 case TextureEnvParameter::Mode:
1166 case TextureEnvParameter::CombineRgb:
1167 case TextureEnvParameter::CombineAlpha:
1168 case TextureEnvParameter::Src0Rgb:
1169 case TextureEnvParameter::Src1Rgb:
1170 case TextureEnvParameter::Src2Rgb:
1171 case TextureEnvParameter::Src0Alpha:
1172 case TextureEnvParameter::Src1Alpha:
1173 case TextureEnvParameter::Src2Alpha:
1174 case TextureEnvParameter::Op0Rgb:
1175 case TextureEnvParameter::Op1Rgb:
1176 case TextureEnvParameter::Op2Rgb:
1177 case TextureEnvParameter::Op0Alpha:
1178 case TextureEnvParameter::Op1Alpha:
1179 case TextureEnvParameter::Op2Alpha:
1180 case TextureEnvParameter::PointCoordReplace:
1181 return true;
1182 default:
1183 return false;
1184 }
1185 }
1186
GetShaderProgramId(ProgramPipeline * programPipeline,ShaderType shaderType,GLint * params)1187 void GetShaderProgramId(ProgramPipeline *programPipeline, ShaderType shaderType, GLint *params)
1188 {
1189 ASSERT(params);
1190
1191 *params = 0;
1192 if (programPipeline)
1193 {
1194 const Program *program = programPipeline->getShaderProgram(shaderType);
1195 if (program)
1196 {
1197 *params = program->id().value;
1198 }
1199 }
1200 }
1201
1202 } // namespace
1203
QueryFramebufferAttachmentParameteriv(const Context * context,const Framebuffer * framebuffer,GLenum attachment,GLenum pname,GLint * params)1204 void QueryFramebufferAttachmentParameteriv(const Context *context,
1205 const Framebuffer *framebuffer,
1206 GLenum attachment,
1207 GLenum pname,
1208 GLint *params)
1209 {
1210 ASSERT(framebuffer);
1211
1212 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
1213
1214 if (attachmentObject == nullptr)
1215 {
1216 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
1217 // is NONE, then querying any other pname will generate INVALID_ENUM.
1218
1219 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
1220 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
1221 // INVALID_OPERATION for all other pnames
1222
1223 switch (pname)
1224 {
1225 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1226 *params = GL_NONE;
1227 break;
1228
1229 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1230 *params = 0;
1231 break;
1232
1233 default:
1234 UNREACHABLE();
1235 break;
1236 }
1237
1238 return;
1239 }
1240
1241 switch (pname)
1242 {
1243 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1244 *params = attachmentObject->type();
1245 break;
1246
1247 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1248 *params = attachmentObject->id();
1249 break;
1250
1251 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1252 *params = attachmentObject->mipLevel();
1253 break;
1254
1255 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1256 {
1257 TextureTarget face = attachmentObject->cubeMapFace();
1258 if (face != TextureTarget::InvalidEnum)
1259 {
1260 *params = ToGLenum(attachmentObject->cubeMapFace());
1261 }
1262 else
1263 {
1264 // This happens when the attachment isn't a texture cube map face
1265 *params = GL_NONE;
1266 }
1267 }
1268 break;
1269
1270 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
1271 *params = attachmentObject->getRedSize();
1272 break;
1273
1274 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
1275 *params = attachmentObject->getGreenSize();
1276 break;
1277
1278 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
1279 *params = attachmentObject->getBlueSize();
1280 break;
1281
1282 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
1283 *params = attachmentObject->getAlphaSize();
1284 break;
1285
1286 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
1287 *params = attachmentObject->getDepthSize();
1288 break;
1289
1290 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
1291 *params = attachmentObject->getStencilSize();
1292 break;
1293
1294 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
1295 *params = attachmentObject->getComponentType();
1296 break;
1297
1298 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
1299 *params = attachmentObject->getColorEncoding();
1300 break;
1301
1302 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
1303 *params = attachmentObject->layer();
1304 break;
1305
1306 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
1307 *params = attachmentObject->getNumViews();
1308 break;
1309
1310 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
1311 *params = attachmentObject->getBaseViewIndex();
1312 break;
1313
1314 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
1315 *params = attachmentObject->isLayered();
1316 break;
1317
1318 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
1319 if (attachmentObject->type() == GL_TEXTURE)
1320 {
1321 *params = attachmentObject->getSamples();
1322 }
1323 else
1324 {
1325 *params = 0;
1326 }
1327 break;
1328
1329 default:
1330 UNREACHABLE();
1331 break;
1332 }
1333 }
1334
QueryBufferParameteriv(const Buffer * buffer,GLenum pname,GLint * params)1335 void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
1336 {
1337 QueryBufferParameterBase(buffer, pname, params);
1338 }
1339
QueryBufferParameteri64v(const Buffer * buffer,GLenum pname,GLint64 * params)1340 void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
1341 {
1342 QueryBufferParameterBase(buffer, pname, params);
1343 }
1344
QueryBufferPointerv(const Buffer * buffer,GLenum pname,void ** params)1345 void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
1346 {
1347 switch (pname)
1348 {
1349 case GL_BUFFER_MAP_POINTER:
1350 *params = buffer->getMapPointer();
1351 break;
1352
1353 default:
1354 UNREACHABLE();
1355 break;
1356 }
1357 }
1358
QueryProgramiv(Context * context,Program * program,GLenum pname,GLint * params)1359 void QueryProgramiv(Context *context, Program *program, GLenum pname, GLint *params)
1360 {
1361 ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1362
1363 switch (pname)
1364 {
1365 case GL_DELETE_STATUS:
1366 *params = program->isFlaggedForDeletion();
1367 return;
1368 case GL_LINK_STATUS:
1369 *params = program->isLinked();
1370 return;
1371 case GL_COMPLETION_STATUS_KHR:
1372 if (context->isContextLost())
1373 {
1374 *params = GL_TRUE;
1375 }
1376 else
1377 {
1378 *params = program->isLinking() ? GL_FALSE : GL_TRUE;
1379 }
1380 return;
1381 case GL_VALIDATE_STATUS:
1382 *params = program->isValidated();
1383 return;
1384 case GL_INFO_LOG_LENGTH:
1385 *params = program->getInfoLogLength();
1386 return;
1387 case GL_ATTACHED_SHADERS:
1388 *params = program->getAttachedShadersCount();
1389 return;
1390 case GL_ACTIVE_ATTRIBUTES:
1391 *params = static_cast<GLint>(program->getExecutable().getProgramInputs().size());
1392 return;
1393 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1394 *params = program->getExecutable().getActiveAttributeMaxLength();
1395 return;
1396 case GL_ACTIVE_UNIFORMS:
1397 *params = static_cast<GLint>(program->getExecutable().getUniforms().size());
1398 return;
1399 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1400 *params = program->getExecutable().getActiveUniformMaxLength();
1401 return;
1402 case GL_PROGRAM_BINARY_READY_ANGLE:
1403 *params = program->isBinaryReady(context);
1404 return;
1405 case GL_PROGRAM_BINARY_LENGTH_OES:
1406 *params = context->getCaps().programBinaryFormats.empty()
1407 ? 0
1408 : program->getBinaryLength(context);
1409 return;
1410 case GL_ACTIVE_UNIFORM_BLOCKS:
1411 *params = static_cast<GLint>(program->getExecutable().getUniformBlocks().size());
1412 return;
1413 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
1414 *params = program->getExecutable().getActiveUniformBlockMaxNameLength();
1415 break;
1416 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
1417 *params = program->getExecutable().getTransformFeedbackBufferMode();
1418 break;
1419 case GL_TRANSFORM_FEEDBACK_VARYINGS:
1420 *params = clampCast<GLint>(
1421 program->getExecutable().getLinkedTransformFeedbackVaryings().size());
1422 break;
1423 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
1424 *params = program->getExecutable().getTransformFeedbackVaryingMaxLength();
1425 break;
1426 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1427 *params = program->getBinaryRetrievableHint();
1428 break;
1429 case GL_PROGRAM_SEPARABLE:
1430 // From es31cSeparateShaderObjsTests.cpp:
1431 // ProgramParameteri PROGRAM_SEPARABLE
1432 // NOTE: The query for PROGRAM_SEPARABLE must query latched
1433 // state. In other words, the state of the binary after
1434 // it was linked. So in the tests below, the queries
1435 // should return the default state GL_FALSE since the
1436 // program has no linked binary.
1437 *params = program->isSeparable() && program->isLinked();
1438 break;
1439 case GL_COMPUTE_WORK_GROUP_SIZE:
1440 {
1441 const sh::WorkGroupSize &localSize =
1442 program->getExecutable().getComputeShaderLocalSize();
1443 params[0] = localSize[0];
1444 params[1] = localSize[1];
1445 params[2] = localSize[2];
1446 }
1447 break;
1448 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
1449 *params = static_cast<GLint>(program->getExecutable().getAtomicCounterBuffers().size());
1450 break;
1451 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
1452 *params = ToGLenum(program->getExecutable().getGeometryShaderInputPrimitiveType());
1453 break;
1454 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
1455 *params = ToGLenum(program->getExecutable().getGeometryShaderOutputPrimitiveType());
1456 break;
1457 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
1458 *params = program->getExecutable().getGeometryShaderMaxVertices();
1459 break;
1460 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
1461 *params = program->getExecutable().getGeometryShaderInvocations();
1462 break;
1463 case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
1464 *params = program->getExecutable().getTessControlShaderVertices();
1465 break;
1466 case GL_TESS_GEN_MODE_EXT:
1467 *params = program->getExecutable().getTessGenMode();
1468 break;
1469 case GL_TESS_GEN_SPACING_EXT:
1470 *params = program->getExecutable().getTessGenSpacing()
1471 ? program->getExecutable().getTessGenSpacing()
1472 : GL_EQUAL;
1473 break;
1474 case GL_TESS_GEN_VERTEX_ORDER:
1475 *params = program->getExecutable().getTessGenVertexOrder()
1476 ? program->getExecutable().getTessGenVertexOrder()
1477 : GL_CCW;
1478 break;
1479 case GL_TESS_GEN_POINT_MODE_EXT:
1480 *params = program->getExecutable().getTessGenPointMode() ? GL_TRUE : GL_FALSE;
1481 break;
1482 default:
1483 UNREACHABLE();
1484 break;
1485 }
1486 }
1487
QueryRenderbufferiv(const Context * context,const Renderbuffer * renderbuffer,GLenum pname,GLint * params)1488 void QueryRenderbufferiv(const Context *context,
1489 const Renderbuffer *renderbuffer,
1490 GLenum pname,
1491 GLint *params)
1492 {
1493 ASSERT(renderbuffer != nullptr);
1494
1495 switch (pname)
1496 {
1497 case GL_RENDERBUFFER_WIDTH:
1498 *params = renderbuffer->getWidth();
1499 break;
1500 case GL_RENDERBUFFER_HEIGHT:
1501 *params = renderbuffer->getHeight();
1502 break;
1503 case GL_RENDERBUFFER_INTERNAL_FORMAT:
1504 // Special case the WebGL 1 DEPTH_STENCIL format.
1505 if (context->isWebGL1() &&
1506 renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
1507 {
1508 *params = GL_DEPTH_STENCIL;
1509 }
1510 else
1511 {
1512 *params = renderbuffer->getFormat().info->internalFormat;
1513 }
1514 break;
1515 case GL_RENDERBUFFER_RED_SIZE:
1516 *params = renderbuffer->getRedSize();
1517 break;
1518 case GL_RENDERBUFFER_GREEN_SIZE:
1519 *params = renderbuffer->getGreenSize();
1520 break;
1521 case GL_RENDERBUFFER_BLUE_SIZE:
1522 *params = renderbuffer->getBlueSize();
1523 break;
1524 case GL_RENDERBUFFER_ALPHA_SIZE:
1525 *params = renderbuffer->getAlphaSize();
1526 break;
1527 case GL_RENDERBUFFER_DEPTH_SIZE:
1528 *params = renderbuffer->getDepthSize();
1529 break;
1530 case GL_RENDERBUFFER_STENCIL_SIZE:
1531 *params = renderbuffer->getStencilSize();
1532 break;
1533 case GL_RENDERBUFFER_SAMPLES_ANGLE:
1534 *params = renderbuffer->getState().getSamples();
1535 break;
1536 case GL_MEMORY_SIZE_ANGLE:
1537 *params = renderbuffer->getMemorySize();
1538 break;
1539 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1540 *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
1541 break;
1542 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1543 *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
1544 break;
1545 case GL_RESOURCE_INITIALIZED_ANGLE:
1546 *params = (renderbuffer->initState(GL_NONE, ImageIndex()) == InitState::Initialized);
1547 break;
1548 default:
1549 UNREACHABLE();
1550 break;
1551 }
1552 }
1553
QueryShaderiv(const Context * context,Shader * shader,GLenum pname,GLint * params)1554 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
1555 {
1556 ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1557
1558 switch (pname)
1559 {
1560 case GL_SHADER_TYPE:
1561 *params = static_cast<GLint>(ToGLenum(shader->getType()));
1562 return;
1563 case GL_DELETE_STATUS:
1564 *params = shader->isFlaggedForDeletion();
1565 return;
1566 case GL_COMPILE_STATUS:
1567 *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
1568 return;
1569 case GL_COMPLETION_STATUS_KHR:
1570 if (context->isContextLost())
1571 {
1572 *params = GL_TRUE;
1573 }
1574 else
1575 {
1576 *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
1577 }
1578 return;
1579 case GL_INFO_LOG_LENGTH:
1580 *params = shader->getInfoLogLength(context);
1581 return;
1582 case GL_SHADER_SOURCE_LENGTH:
1583 *params = shader->getSourceLength();
1584 return;
1585 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
1586 *params = shader->getTranslatedSourceWithDebugInfoLength(context);
1587 return;
1588 default:
1589 UNREACHABLE();
1590 break;
1591 }
1592 }
1593
QueryTexLevelParameterfv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLfloat * params)1594 void QueryTexLevelParameterfv(const Texture *texture,
1595 TextureTarget target,
1596 GLint level,
1597 GLenum pname,
1598 GLfloat *params)
1599 {
1600 QueryTexLevelParameterBase(texture, target, level, pname, params);
1601 }
1602
QueryTexLevelParameteriv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLint * params)1603 void QueryTexLevelParameteriv(const Texture *texture,
1604 TextureTarget target,
1605 GLint level,
1606 GLenum pname,
1607 GLint *params)
1608 {
1609 QueryTexLevelParameterBase(texture, target, level, pname, params);
1610 }
1611
QueryTexParameterfv(const Context * context,const Texture * texture,GLenum pname,GLfloat * params)1612 void QueryTexParameterfv(const Context *context,
1613 const Texture *texture,
1614 GLenum pname,
1615 GLfloat *params)
1616 {
1617 QueryTexParameterBase<false, false>(context, texture, pname, params);
1618 }
1619
QueryTexParameterxv(const Context * context,const Texture * texture,GLenum pname,GLfixed * params)1620 void QueryTexParameterxv(const Context *context,
1621 const Texture *texture,
1622 GLenum pname,
1623 GLfixed *params)
1624 {
1625 QueryTexParameterBase<false, true>(context, texture, pname, params);
1626 }
1627
QueryTexParameteriv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1628 void QueryTexParameteriv(const Context *context,
1629 const Texture *texture,
1630 GLenum pname,
1631 GLint *params)
1632 {
1633 QueryTexParameterBase<false, false>(context, texture, pname, params);
1634 }
1635
QueryTexParameterIiv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1636 void QueryTexParameterIiv(const Context *context,
1637 const Texture *texture,
1638 GLenum pname,
1639 GLint *params)
1640 {
1641 QueryTexParameterBase<true, false>(context, texture, pname, params);
1642 }
1643
QueryTexParameterIuiv(const Context * context,const Texture * texture,GLenum pname,GLuint * params)1644 void QueryTexParameterIuiv(const Context *context,
1645 const Texture *texture,
1646 GLenum pname,
1647 GLuint *params)
1648 {
1649 QueryTexParameterBase<true, false>(context, texture, pname, params);
1650 }
1651
QuerySamplerParameterfv(const Sampler * sampler,GLenum pname,GLfloat * params)1652 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
1653 {
1654 QuerySamplerParameterBase<false>(sampler, pname, params);
1655 }
1656
QuerySamplerParameteriv(const Sampler * sampler,GLenum pname,GLint * params)1657 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
1658 {
1659 QuerySamplerParameterBase<false>(sampler, pname, params);
1660 }
1661
QuerySamplerParameterIiv(const Sampler * sampler,GLenum pname,GLint * params)1662 void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
1663 {
1664 QuerySamplerParameterBase<true>(sampler, pname, params);
1665 }
1666
QuerySamplerParameterIuiv(const Sampler * sampler,GLenum pname,GLuint * params)1667 void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
1668 {
1669 QuerySamplerParameterBase<true>(sampler, pname, params);
1670 }
1671
QueryVertexAttribfv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLfloat * params)1672 void QueryVertexAttribfv(const VertexAttribute &attrib,
1673 const VertexBinding &binding,
1674 const VertexAttribCurrentValueData ¤tValueData,
1675 GLenum pname,
1676 GLfloat *params)
1677 {
1678 QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1679 }
1680
QueryVertexAttribiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1681 void QueryVertexAttribiv(const VertexAttribute &attrib,
1682 const VertexBinding &binding,
1683 const VertexAttribCurrentValueData ¤tValueData,
1684 GLenum pname,
1685 GLint *params)
1686 {
1687 QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1688 }
1689
QueryVertexAttribPointerv(const VertexAttribute & attrib,GLenum pname,void ** pointer)1690 void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
1691 {
1692 switch (pname)
1693 {
1694 case GL_VERTEX_ATTRIB_ARRAY_POINTER:
1695 *pointer = const_cast<void *>(attrib.pointer);
1696 break;
1697
1698 default:
1699 UNREACHABLE();
1700 break;
1701 }
1702 }
1703
QueryVertexAttribIiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1704 void QueryVertexAttribIiv(const VertexAttribute &attrib,
1705 const VertexBinding &binding,
1706 const VertexAttribCurrentValueData ¤tValueData,
1707 GLenum pname,
1708 GLint *params)
1709 {
1710 QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
1711 }
1712
QueryVertexAttribIuiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLuint * params)1713 void QueryVertexAttribIuiv(const VertexAttribute &attrib,
1714 const VertexBinding &binding,
1715 const VertexAttribCurrentValueData ¤tValueData,
1716 GLenum pname,
1717 GLuint *params)
1718 {
1719 QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
1720 params);
1721 }
1722
QueryActiveUniformBlockiv(const Program * program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLint * params)1723 void QueryActiveUniformBlockiv(const Program *program,
1724 UniformBlockIndex uniformBlockIndex,
1725 GLenum pname,
1726 GLint *params)
1727 {
1728 GLenum prop = GetUniformBlockPropertyEnum(pname);
1729 QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
1730 std::numeric_limits<GLsizei>::max(), nullptr, params);
1731 }
1732
QueryInternalFormativ(const TextureCaps & format,GLenum pname,GLsizei bufSize,GLint * params)1733 void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
1734 {
1735 switch (pname)
1736 {
1737 case GL_NUM_SAMPLE_COUNTS:
1738 if (bufSize != 0)
1739 {
1740 *params = clampCast<GLint>(format.sampleCounts.size());
1741 }
1742 break;
1743
1744 case GL_SAMPLES:
1745 {
1746 size_t returnCount = std::min<size_t>(bufSize, format.sampleCounts.size());
1747 auto sampleReverseIt = format.sampleCounts.rbegin();
1748 for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
1749 {
1750 params[sampleIndex] = *sampleReverseIt++;
1751 }
1752 }
1753 break;
1754
1755 default:
1756 UNREACHABLE();
1757 break;
1758 }
1759 }
1760
QueryFramebufferParameteriv(const Framebuffer * framebuffer,GLenum pname,GLint * params)1761 void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
1762 {
1763 ASSERT(framebuffer);
1764
1765 switch (pname)
1766 {
1767 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1768 *params = framebuffer->getDefaultWidth();
1769 break;
1770 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1771 *params = framebuffer->getDefaultHeight();
1772 break;
1773 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1774 *params = framebuffer->getDefaultSamples();
1775 break;
1776 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1777 *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
1778 break;
1779 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1780 *params = framebuffer->getDefaultLayers();
1781 break;
1782 case GL_FRAMEBUFFER_FLIP_Y_MESA:
1783 *params = ConvertToGLBoolean(framebuffer->getFlipY());
1784 break;
1785 default:
1786 UNREACHABLE();
1787 break;
1788 }
1789 }
1790
QuerySynciv(const Context * context,const Sync * sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)1791 angle::Result QuerySynciv(const Context *context,
1792 const Sync *sync,
1793 GLenum pname,
1794 GLsizei bufSize,
1795 GLsizei *length,
1796 GLint *values)
1797 {
1798 ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
1799
1800 // All queries return one value, exit early if the buffer can't fit anything.
1801 if (bufSize < 1)
1802 {
1803 if (length != nullptr)
1804 {
1805 *length = 0;
1806 }
1807 return angle::Result::Continue;
1808 }
1809
1810 switch (pname)
1811 {
1812 case GL_OBJECT_TYPE:
1813 *values = clampCast<GLint>(GL_SYNC_FENCE);
1814 break;
1815 case GL_SYNC_CONDITION:
1816 *values = clampCast<GLint>(sync->getCondition());
1817 break;
1818 case GL_SYNC_FLAGS:
1819 *values = clampCast<GLint>(sync->getFlags());
1820 break;
1821 case GL_SYNC_STATUS:
1822 if (context->isContextLost())
1823 {
1824 *values = GL_SIGNALED;
1825 }
1826 else
1827 {
1828 ANGLE_TRY(sync->getStatus(context, values));
1829 }
1830 break;
1831
1832 default:
1833 UNREACHABLE();
1834 break;
1835 }
1836
1837 if (length != nullptr)
1838 {
1839 *length = 1;
1840 }
1841
1842 return angle::Result::Continue;
1843 }
1844
SetTexParameterx(Context * context,Texture * texture,GLenum pname,GLfixed param)1845 void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
1846 {
1847 SetTexParameterBase<false, true>(context, texture, pname, ¶m);
1848 }
1849
SetTexParameterxv(Context * context,Texture * texture,GLenum pname,const GLfixed * params)1850 void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
1851 {
1852 SetTexParameterBase<false, true>(context, texture, pname, params);
1853 }
1854
SetTexParameterf(Context * context,Texture * texture,GLenum pname,GLfloat param)1855 void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
1856 {
1857 SetTexParameterBase<false, false>(context, texture, pname, ¶m);
1858 }
1859
SetTexParameterfv(Context * context,Texture * texture,GLenum pname,const GLfloat * params)1860 void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
1861 {
1862 SetTexParameterBase<false, false>(context, texture, pname, params);
1863 }
1864
SetTexParameteri(Context * context,Texture * texture,GLenum pname,GLint param)1865 void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
1866 {
1867 SetTexParameterBase<false, false>(context, texture, pname, ¶m);
1868 }
1869
SetTexParameteriv(Context * context,Texture * texture,GLenum pname,const GLint * params)1870 void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1871 {
1872 SetTexParameterBase<false, false>(context, texture, pname, params);
1873 }
1874
SetTexParameterIiv(Context * context,Texture * texture,GLenum pname,const GLint * params)1875 void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1876 {
1877 SetTexParameterBase<true, false>(context, texture, pname, params);
1878 }
1879
SetTexParameterIuiv(Context * context,Texture * texture,GLenum pname,const GLuint * params)1880 void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
1881 {
1882 SetTexParameterBase<true, false>(context, texture, pname, params);
1883 }
1884
SetSamplerParameterf(Context * context,Sampler * sampler,GLenum pname,GLfloat param)1885 void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
1886 {
1887 SetSamplerParameterBase<false>(context, sampler, pname, ¶m);
1888 }
1889
SetSamplerParameterfv(Context * context,Sampler * sampler,GLenum pname,const GLfloat * params)1890 void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
1891 {
1892 SetSamplerParameterBase<false>(context, sampler, pname, params);
1893 }
1894
SetSamplerParameteri(Context * context,Sampler * sampler,GLenum pname,GLint param)1895 void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
1896 {
1897 SetSamplerParameterBase<false>(context, sampler, pname, ¶m);
1898 }
1899
SetSamplerParameteriv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1900 void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1901 {
1902 SetSamplerParameterBase<false>(context, sampler, pname, params);
1903 }
1904
SetSamplerParameterIiv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1905 void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1906 {
1907 SetSamplerParameterBase<true>(context, sampler, pname, params);
1908 }
1909
SetSamplerParameterIuiv(Context * context,Sampler * sampler,GLenum pname,const GLuint * params)1910 void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
1911 {
1912 SetSamplerParameterBase<true>(context, sampler, pname, params);
1913 }
1914
SetFramebufferParameteri(const Context * context,Framebuffer * framebuffer,GLenum pname,GLint param)1915 void SetFramebufferParameteri(const Context *context,
1916 Framebuffer *framebuffer,
1917 GLenum pname,
1918 GLint param)
1919 {
1920 ASSERT(framebuffer);
1921
1922 switch (pname)
1923 {
1924 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1925 framebuffer->setDefaultWidth(context, param);
1926 break;
1927 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1928 framebuffer->setDefaultHeight(context, param);
1929 break;
1930 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1931 framebuffer->setDefaultSamples(context, param);
1932 break;
1933 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1934 framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
1935 break;
1936 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1937 framebuffer->setDefaultLayers(param);
1938 break;
1939 case GL_FRAMEBUFFER_FLIP_Y_MESA:
1940 framebuffer->setFlipY(ConvertToBool(param));
1941 break;
1942 default:
1943 UNREACHABLE();
1944 break;
1945 }
1946 }
1947
SetProgramParameteri(const Context * context,Program * program,GLenum pname,GLint value)1948 void SetProgramParameteri(const Context *context, Program *program, GLenum pname, GLint value)
1949 {
1950 ASSERT(program);
1951
1952 switch (pname)
1953 {
1954 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1955 program->setBinaryRetrievableHint(ConvertToBool(value));
1956 break;
1957 case GL_PROGRAM_SEPARABLE:
1958 program->setSeparable(context, ConvertToBool(value));
1959 break;
1960 default:
1961 UNREACHABLE();
1962 break;
1963 }
1964 }
1965
GetUniformResourceProperty(const Program * program,GLuint index,const GLenum prop)1966 GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
1967 {
1968 const ProgramExecutable &executable = program->getExecutable();
1969 const LinkedUniform &uniform = executable.getUniformByIndex(index);
1970
1971 GLenum resourceProp = GetUniformPropertyEnum(prop);
1972 switch (resourceProp)
1973 {
1974 case GL_TYPE:
1975 return clampCast<GLint>(uniform.getType());
1976
1977 case GL_ARRAY_SIZE:
1978 return clampCast<GLint>(uniform.getBasicTypeElementCount());
1979
1980 case GL_NAME_LENGTH:
1981 return clampCast<GLint>(executable.getUniformNameByIndex(index).size() + 1u);
1982
1983 case GL_LOCATION:
1984 return executable.getUniformLocation(executable.getUniformNameByIndex(index)).value;
1985
1986 case GL_BLOCK_INDEX:
1987 return (uniform.isAtomicCounter() ? -1 : uniform.getBufferIndex());
1988
1989 case GL_OFFSET:
1990 return uniform.pod.flagBits.isBlock ? uniform.pod.blockOffset : -1;
1991
1992 case GL_ARRAY_STRIDE:
1993 return uniform.pod.flagBits.isBlock ? uniform.pod.blockArrayStride : -1;
1994
1995 case GL_MATRIX_STRIDE:
1996 return uniform.pod.flagBits.isBlock ? uniform.pod.blockMatrixStride : -1;
1997
1998 case GL_IS_ROW_MAJOR:
1999 return uniform.pod.flagBits.blockIsRowMajorMatrix ? 1 : 0;
2000
2001 case GL_REFERENCED_BY_VERTEX_SHADER:
2002 return uniform.isActive(ShaderType::Vertex);
2003
2004 case GL_REFERENCED_BY_FRAGMENT_SHADER:
2005 return uniform.isActive(ShaderType::Fragment);
2006
2007 case GL_REFERENCED_BY_COMPUTE_SHADER:
2008 return uniform.isActive(ShaderType::Compute);
2009
2010 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
2011 return uniform.isActive(ShaderType::Geometry);
2012
2013 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
2014 return uniform.isActive(ShaderType::TessControl);
2015
2016 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
2017 return uniform.isActive(ShaderType::TessEvaluation);
2018
2019 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
2020 return (uniform.isAtomicCounter() ? uniform.getBufferIndex() : -1);
2021
2022 default:
2023 UNREACHABLE();
2024 return 0;
2025 }
2026 }
2027
GetBufferVariableResourceProperty(const Program * program,GLuint index,const GLenum prop)2028 GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
2029 {
2030 const ProgramExecutable &executable = program->getExecutable();
2031 const BufferVariable &bufferVariable = executable.getBufferVariableByIndex(index);
2032
2033 switch (prop)
2034 {
2035 case GL_TYPE:
2036 case GL_ARRAY_SIZE:
2037 case GL_NAME_LENGTH:
2038 return GetCommonVariableProperty(bufferVariable, prop);
2039
2040 case GL_BLOCK_INDEX:
2041 return bufferVariable.pod.bufferIndex;
2042
2043 case GL_OFFSET:
2044 return bufferVariable.pod.blockInfo.offset;
2045
2046 case GL_ARRAY_STRIDE:
2047 return bufferVariable.pod.blockInfo.arrayStride;
2048
2049 case GL_MATRIX_STRIDE:
2050 return bufferVariable.pod.blockInfo.matrixStride;
2051
2052 case GL_IS_ROW_MAJOR:
2053 return static_cast<GLint>(bufferVariable.pod.blockInfo.isRowMajorMatrix);
2054
2055 case GL_REFERENCED_BY_VERTEX_SHADER:
2056 return bufferVariable.isActive(ShaderType::Vertex);
2057
2058 case GL_REFERENCED_BY_FRAGMENT_SHADER:
2059 return bufferVariable.isActive(ShaderType::Fragment);
2060
2061 case GL_REFERENCED_BY_COMPUTE_SHADER:
2062 return bufferVariable.isActive(ShaderType::Compute);
2063
2064 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
2065 return bufferVariable.isActive(ShaderType::Geometry);
2066
2067 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
2068 return bufferVariable.isActive(ShaderType::TessControl);
2069
2070 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
2071 return bufferVariable.isActive(ShaderType::TessEvaluation);
2072
2073 case GL_TOP_LEVEL_ARRAY_SIZE:
2074 return bufferVariable.pod.topLevelArraySize;
2075
2076 case GL_TOP_LEVEL_ARRAY_STRIDE:
2077 return bufferVariable.pod.blockInfo.topLevelArrayStride;
2078
2079 default:
2080 UNREACHABLE();
2081 return 0;
2082 }
2083 }
2084
QueryProgramResourceIndex(const Program * program,GLenum programInterface,const GLchar * name)2085 GLuint QueryProgramResourceIndex(const Program *program,
2086 GLenum programInterface,
2087 const GLchar *name)
2088 {
2089 const ProgramExecutable &executable = program->getExecutable();
2090
2091 switch (programInterface)
2092 {
2093 case GL_PROGRAM_INPUT:
2094 return executable.getInputResourceIndex(name);
2095
2096 case GL_PROGRAM_OUTPUT:
2097 return executable.getOutputResourceIndex(name);
2098
2099 case GL_UNIFORM:
2100 return executable.getUniformIndexFromName(name);
2101
2102 case GL_BUFFER_VARIABLE:
2103 return executable.getBufferVariableIndexFromName(name);
2104
2105 case GL_SHADER_STORAGE_BLOCK:
2106 return executable.getShaderStorageBlockIndex(name);
2107
2108 case GL_UNIFORM_BLOCK:
2109 return executable.getUniformBlockIndex(name);
2110
2111 case GL_TRANSFORM_FEEDBACK_VARYING:
2112 return executable.getTransformFeedbackVaryingResourceIndex(name);
2113
2114 default:
2115 UNREACHABLE();
2116 return GL_INVALID_INDEX;
2117 }
2118 }
2119
QueryProgramResourceName(const Context * context,const Program * program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)2120 void QueryProgramResourceName(const Context *context,
2121 const Program *program,
2122 GLenum programInterface,
2123 GLuint index,
2124 GLsizei bufSize,
2125 GLsizei *length,
2126 GLchar *name)
2127 {
2128 const ProgramExecutable &executable = program->getExecutable();
2129
2130 switch (programInterface)
2131 {
2132 case GL_PROGRAM_INPUT:
2133 executable.getInputResourceName(index, bufSize, length, name);
2134 break;
2135
2136 case GL_PROGRAM_OUTPUT:
2137 executable.getOutputResourceName(index, bufSize, length, name);
2138 break;
2139
2140 case GL_UNIFORM:
2141 executable.getUniformResourceName(index, bufSize, length, name);
2142 break;
2143
2144 case GL_BUFFER_VARIABLE:
2145 executable.getBufferVariableResourceName(index, bufSize, length, name);
2146 break;
2147
2148 case GL_SHADER_STORAGE_BLOCK:
2149 executable.getActiveShaderStorageBlockName(index, bufSize, length, name);
2150 break;
2151
2152 case GL_UNIFORM_BLOCK:
2153 executable.getActiveUniformBlockName(context, {index}, bufSize, length, name);
2154 break;
2155
2156 case GL_TRANSFORM_FEEDBACK_VARYING:
2157 executable.getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
2158 break;
2159
2160 default:
2161 UNREACHABLE();
2162 }
2163 }
2164
QueryProgramResourceLocation(const Program * program,GLenum programInterface,const GLchar * name)2165 GLint QueryProgramResourceLocation(const Program *program,
2166 GLenum programInterface,
2167 const GLchar *name)
2168 {
2169 const ProgramExecutable &executable = program->getExecutable();
2170
2171 switch (programInterface)
2172 {
2173 case GL_PROGRAM_INPUT:
2174 return executable.getInputResourceLocation(name);
2175
2176 case GL_PROGRAM_OUTPUT:
2177 return executable.getOutputResourceLocation(name);
2178
2179 case GL_UNIFORM:
2180 return executable.getUniformLocation(name).value;
2181
2182 default:
2183 UNREACHABLE();
2184 return -1;
2185 }
2186 }
2187
QueryProgramResourceiv(const Program * program,GLenum programInterface,UniformBlockIndex index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)2188 void QueryProgramResourceiv(const Program *program,
2189 GLenum programInterface,
2190 UniformBlockIndex index,
2191 GLsizei propCount,
2192 const GLenum *props,
2193 GLsizei bufSize,
2194 GLsizei *length,
2195 GLint *params)
2196 {
2197 if (!program->isLinked())
2198 {
2199 return;
2200 }
2201
2202 if (length != nullptr)
2203 {
2204 *length = 0;
2205 }
2206
2207 if (bufSize == 0)
2208 {
2209 // No room to write the results
2210 return;
2211 }
2212
2213 GLsizei pos = 0;
2214 for (GLsizei i = 0; i < propCount; i++)
2215 {
2216 switch (programInterface)
2217 {
2218 case GL_PROGRAM_INPUT:
2219 params[i] = GetInputResourceProperty(program, index.value, props[i]);
2220 ++pos;
2221 break;
2222
2223 case GL_PROGRAM_OUTPUT:
2224 params[i] = GetOutputResourceProperty(program, index.value, props[i]);
2225 ++pos;
2226 break;
2227
2228 case GL_UNIFORM:
2229 params[i] = GetUniformResourceProperty(program, index.value, props[i]);
2230 ++pos;
2231 break;
2232
2233 case GL_BUFFER_VARIABLE:
2234 params[i] = GetBufferVariableResourceProperty(program, index.value, props[i]);
2235 ++pos;
2236 break;
2237
2238 case GL_UNIFORM_BLOCK:
2239 GetUniformBlockResourceProperty(program, index.value, props[i], params, bufSize,
2240 &pos);
2241 break;
2242
2243 case GL_SHADER_STORAGE_BLOCK:
2244 GetShaderStorageBlockResourceProperty(program, index.value, props[i], params,
2245 bufSize, &pos);
2246 break;
2247
2248 case GL_ATOMIC_COUNTER_BUFFER:
2249 GetAtomicCounterBufferResourceProperty(program, index.value, props[i], params,
2250 bufSize, &pos);
2251 break;
2252
2253 case GL_TRANSFORM_FEEDBACK_VARYING:
2254 params[i] =
2255 GetTransformFeedbackVaryingResourceProperty(program, index.value, props[i]);
2256 ++pos;
2257 break;
2258
2259 default:
2260 UNREACHABLE();
2261 params[i] = GL_INVALID_VALUE;
2262 }
2263 if (pos == bufSize)
2264 {
2265 // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
2266 // This checks not to break buffer bounds for such case.
2267 break;
2268 }
2269 }
2270
2271 if (length != nullptr)
2272 {
2273 *length = pos;
2274 }
2275 }
2276
QueryProgramInterfaceiv(const Program * program,GLenum programInterface,GLenum pname,GLint * params)2277 void QueryProgramInterfaceiv(const Program *program,
2278 GLenum programInterface,
2279 GLenum pname,
2280 GLint *params)
2281 {
2282 switch (pname)
2283 {
2284 case GL_ACTIVE_RESOURCES:
2285 *params = QueryProgramInterfaceActiveResources(program, programInterface);
2286 break;
2287
2288 case GL_MAX_NAME_LENGTH:
2289 *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
2290 break;
2291
2292 case GL_MAX_NUM_ACTIVE_VARIABLES:
2293 *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
2294 break;
2295
2296 default:
2297 UNREACHABLE();
2298 }
2299 }
2300
SetMemoryObjectParameteriv(const Context * context,MemoryObject * memoryObject,GLenum pname,const GLint * params)2301 angle::Result SetMemoryObjectParameteriv(const Context *context,
2302 MemoryObject *memoryObject,
2303 GLenum pname,
2304 const GLint *params)
2305 {
2306 switch (pname)
2307 {
2308 case GL_DEDICATED_MEMORY_OBJECT_EXT:
2309 ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
2310 break;
2311
2312 case GL_PROTECTED_MEMORY_OBJECT_EXT:
2313 ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0])));
2314 break;
2315
2316 default:
2317 UNREACHABLE();
2318 }
2319
2320 return angle::Result::Continue;
2321 }
2322
QueryMemoryObjectParameteriv(const MemoryObject * memoryObject,GLenum pname,GLint * params)2323 void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
2324 {
2325 switch (pname)
2326 {
2327 case GL_DEDICATED_MEMORY_OBJECT_EXT:
2328 *params = memoryObject->isDedicatedMemory();
2329 break;
2330
2331 case GL_PROTECTED_MEMORY_OBJECT_EXT:
2332 *params = memoryObject->isProtectedMemory();
2333 break;
2334
2335 default:
2336 UNREACHABLE();
2337 }
2338 }
2339
ParamToVertexArrayType(GLenum param)2340 ClientVertexArrayType ParamToVertexArrayType(GLenum param)
2341 {
2342 switch (param)
2343 {
2344 case GL_VERTEX_ARRAY:
2345 case GL_VERTEX_ARRAY_BUFFER_BINDING:
2346 case GL_VERTEX_ARRAY_STRIDE:
2347 case GL_VERTEX_ARRAY_SIZE:
2348 case GL_VERTEX_ARRAY_TYPE:
2349 case GL_VERTEX_ARRAY_POINTER:
2350 return ClientVertexArrayType::Vertex;
2351 case GL_NORMAL_ARRAY:
2352 case GL_NORMAL_ARRAY_BUFFER_BINDING:
2353 case GL_NORMAL_ARRAY_STRIDE:
2354 case GL_NORMAL_ARRAY_TYPE:
2355 case GL_NORMAL_ARRAY_POINTER:
2356 return ClientVertexArrayType::Normal;
2357 case GL_COLOR_ARRAY:
2358 case GL_COLOR_ARRAY_BUFFER_BINDING:
2359 case GL_COLOR_ARRAY_STRIDE:
2360 case GL_COLOR_ARRAY_SIZE:
2361 case GL_COLOR_ARRAY_TYPE:
2362 case GL_COLOR_ARRAY_POINTER:
2363 return ClientVertexArrayType::Color;
2364 case GL_POINT_SIZE_ARRAY_OES:
2365 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2366 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2367 case GL_POINT_SIZE_ARRAY_TYPE_OES:
2368 case GL_POINT_SIZE_ARRAY_POINTER_OES:
2369 return ClientVertexArrayType::PointSize;
2370 case GL_TEXTURE_COORD_ARRAY:
2371 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2372 case GL_TEXTURE_COORD_ARRAY_STRIDE:
2373 case GL_TEXTURE_COORD_ARRAY_SIZE:
2374 case GL_TEXTURE_COORD_ARRAY_TYPE:
2375 case GL_TEXTURE_COORD_ARRAY_POINTER:
2376 return ClientVertexArrayType::TextureCoord;
2377 default:
2378 UNREACHABLE();
2379 return ClientVertexArrayType::InvalidEnum;
2380 }
2381 }
2382
SetLightModelParameters(GLES1State * state,GLenum pname,const GLfloat * params)2383 void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2384 {
2385 LightModelParameters &lightModel = state->lightModelParameters();
2386
2387 switch (pname)
2388 {
2389 case GL_LIGHT_MODEL_AMBIENT:
2390 lightModel.color = ColorF::fromData(params);
2391 break;
2392 case GL_LIGHT_MODEL_TWO_SIDE:
2393 lightModel.twoSided = *params == 1.0f ? true : false;
2394 break;
2395 default:
2396 break;
2397 }
2398 }
2399
GetLightModelParameters(const GLES1State * state,GLenum pname,GLfloat * params)2400 void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2401 {
2402 const LightModelParameters &lightModel = state->lightModelParameters();
2403
2404 switch (pname)
2405 {
2406 case GL_LIGHT_MODEL_TWO_SIDE:
2407 *params = lightModel.twoSided ? 1.0f : 0.0f;
2408 break;
2409 case GL_LIGHT_MODEL_AMBIENT:
2410 lightModel.color.writeData(params);
2411 break;
2412 default:
2413 break;
2414 }
2415 }
2416
IsLightModelTwoSided(const GLES1State * state)2417 bool IsLightModelTwoSided(const GLES1State *state)
2418 {
2419 return state->lightModelParameters().twoSided;
2420 }
2421
SetLightParameters(GLES1State * state,GLenum light,LightParameter pname,const GLfloat * params)2422 void SetLightParameters(GLES1State *state,
2423 GLenum light,
2424 LightParameter pname,
2425 const GLfloat *params)
2426 {
2427 uint32_t lightIndex = light - GL_LIGHT0;
2428
2429 LightParameters &lightParams = state->lightParameters(lightIndex);
2430
2431 switch (pname)
2432 {
2433 case LightParameter::Ambient:
2434 lightParams.ambient = ColorF::fromData(params);
2435 break;
2436 case LightParameter::Diffuse:
2437 lightParams.diffuse = ColorF::fromData(params);
2438 break;
2439 case LightParameter::Specular:
2440 lightParams.specular = ColorF::fromData(params);
2441 break;
2442 case LightParameter::Position:
2443 {
2444 angle::Mat4 mv = state->getModelviewMatrix();
2445 angle::Vector4 transformedPos =
2446 mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
2447 lightParams.position[0] = transformedPos[0];
2448 lightParams.position[1] = transformedPos[1];
2449 lightParams.position[2] = transformedPos[2];
2450 lightParams.position[3] = transformedPos[3];
2451 }
2452 break;
2453 case LightParameter::SpotDirection:
2454 {
2455 angle::Mat4 mv = state->getModelviewMatrix();
2456 angle::Vector4 transformedPos =
2457 mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
2458 lightParams.direction[0] = transformedPos[0];
2459 lightParams.direction[1] = transformedPos[1];
2460 lightParams.direction[2] = transformedPos[2];
2461 }
2462 break;
2463 case LightParameter::SpotExponent:
2464 lightParams.spotlightExponent = *params;
2465 break;
2466 case LightParameter::SpotCutoff:
2467 lightParams.spotlightCutoffAngle = *params;
2468 break;
2469 case LightParameter::ConstantAttenuation:
2470 lightParams.attenuationConst = *params;
2471 break;
2472 case LightParameter::LinearAttenuation:
2473 lightParams.attenuationLinear = *params;
2474 break;
2475 case LightParameter::QuadraticAttenuation:
2476 lightParams.attenuationQuadratic = *params;
2477 break;
2478 default:
2479 return;
2480 }
2481 }
2482
GetLightParameters(const GLES1State * state,GLenum light,LightParameter pname,GLfloat * params)2483 void GetLightParameters(const GLES1State *state,
2484 GLenum light,
2485 LightParameter pname,
2486 GLfloat *params)
2487 {
2488 uint32_t lightIndex = light - GL_LIGHT0;
2489 const LightParameters &lightParams = state->lightParameters(lightIndex);
2490
2491 switch (pname)
2492 {
2493 case LightParameter::Ambient:
2494 lightParams.ambient.writeData(params);
2495 break;
2496 case LightParameter::Diffuse:
2497 lightParams.diffuse.writeData(params);
2498 break;
2499 case LightParameter::Specular:
2500 lightParams.specular.writeData(params);
2501 break;
2502 case LightParameter::Position:
2503 memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
2504 break;
2505 case LightParameter::SpotDirection:
2506 memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
2507 break;
2508 case LightParameter::SpotExponent:
2509 *params = lightParams.spotlightExponent;
2510 break;
2511 case LightParameter::SpotCutoff:
2512 *params = lightParams.spotlightCutoffAngle;
2513 break;
2514 case LightParameter::ConstantAttenuation:
2515 *params = lightParams.attenuationConst;
2516 break;
2517 case LightParameter::LinearAttenuation:
2518 *params = lightParams.attenuationLinear;
2519 break;
2520 case LightParameter::QuadraticAttenuation:
2521 *params = lightParams.attenuationQuadratic;
2522 break;
2523 default:
2524 break;
2525 }
2526 }
2527
SetMaterialParameters(GLES1State * state,GLenum face,MaterialParameter pname,const GLfloat * params)2528 void SetMaterialParameters(GLES1State *state,
2529 GLenum face,
2530 MaterialParameter pname,
2531 const GLfloat *params)
2532 {
2533 // Note: Ambient and diffuse colors are inherited from glColor when COLOR_MATERIAL is enabled,
2534 // and can only be modified by this function if that is disabled:
2535 //
2536 // > the replaced values remain until changed by either sending a new color or by setting a
2537 // > new material value when COLOR_MATERIAL is not currently enabled, to override that
2538 // particular value.
2539
2540 MaterialParameters &material = state->materialParameters();
2541 switch (pname)
2542 {
2543 case MaterialParameter::Ambient:
2544 if (!state->isColorMaterialEnabled())
2545 {
2546 material.ambient = ColorF::fromData(params);
2547 }
2548 break;
2549 case MaterialParameter::Diffuse:
2550 if (!state->isColorMaterialEnabled())
2551 {
2552 material.diffuse = ColorF::fromData(params);
2553 }
2554 break;
2555 case MaterialParameter::AmbientAndDiffuse:
2556 if (!state->isColorMaterialEnabled())
2557 {
2558 material.ambient = ColorF::fromData(params);
2559 material.diffuse = ColorF::fromData(params);
2560 }
2561 break;
2562 case MaterialParameter::Specular:
2563 material.specular = ColorF::fromData(params);
2564 break;
2565 case MaterialParameter::Emission:
2566 material.emissive = ColorF::fromData(params);
2567 break;
2568 case MaterialParameter::Shininess:
2569 material.specularExponent = *params;
2570 break;
2571 default:
2572 return;
2573 }
2574 }
2575
GetMaterialParameters(const GLES1State * state,GLenum face,MaterialParameter pname,GLfloat * params)2576 void GetMaterialParameters(const GLES1State *state,
2577 GLenum face,
2578 MaterialParameter pname,
2579 GLfloat *params)
2580 {
2581 const ColorF ¤tColor = state->getCurrentColor();
2582 const MaterialParameters &material = state->materialParameters();
2583 const bool colorMaterialEnabled = state->isColorMaterialEnabled();
2584
2585 switch (pname)
2586 {
2587 case MaterialParameter::Ambient:
2588 if (colorMaterialEnabled)
2589 {
2590 currentColor.writeData(params);
2591 }
2592 else
2593 {
2594 material.ambient.writeData(params);
2595 }
2596 break;
2597 case MaterialParameter::Diffuse:
2598 if (colorMaterialEnabled)
2599 {
2600 currentColor.writeData(params);
2601 }
2602 else
2603 {
2604 material.diffuse.writeData(params);
2605 }
2606 break;
2607 case MaterialParameter::Specular:
2608 material.specular.writeData(params);
2609 break;
2610 case MaterialParameter::Emission:
2611 material.emissive.writeData(params);
2612 break;
2613 case MaterialParameter::Shininess:
2614 *params = material.specularExponent;
2615 break;
2616 default:
2617 return;
2618 }
2619 }
2620
GetLightModelParameterCount(GLenum pname)2621 unsigned int GetLightModelParameterCount(GLenum pname)
2622 {
2623 switch (pname)
2624 {
2625 case GL_LIGHT_MODEL_AMBIENT:
2626 return 4;
2627 case GL_LIGHT_MODEL_TWO_SIDE:
2628 return 1;
2629 default:
2630 UNREACHABLE();
2631 return 0;
2632 }
2633 }
2634
GetLightParameterCount(LightParameter pname)2635 unsigned int GetLightParameterCount(LightParameter pname)
2636 {
2637 switch (pname)
2638 {
2639 case LightParameter::Ambient:
2640 case LightParameter::Diffuse:
2641 case LightParameter::AmbientAndDiffuse:
2642 case LightParameter::Specular:
2643 case LightParameter::Position:
2644 return 4;
2645 case LightParameter::SpotDirection:
2646 return 3;
2647 case LightParameter::SpotExponent:
2648 case LightParameter::SpotCutoff:
2649 case LightParameter::ConstantAttenuation:
2650 case LightParameter::LinearAttenuation:
2651 case LightParameter::QuadraticAttenuation:
2652 return 1;
2653 default:
2654 UNREACHABLE();
2655 return 0;
2656 }
2657 }
2658
GetMaterialParameterCount(MaterialParameter pname)2659 unsigned int GetMaterialParameterCount(MaterialParameter pname)
2660 {
2661 switch (pname)
2662 {
2663 case MaterialParameter::Ambient:
2664 case MaterialParameter::Diffuse:
2665 case MaterialParameter::AmbientAndDiffuse:
2666 case MaterialParameter::Specular:
2667 case MaterialParameter::Emission:
2668 return 4;
2669 case MaterialParameter::Shininess:
2670 return 1;
2671 default:
2672 UNREACHABLE();
2673 return 0;
2674 }
2675 }
2676
SetFogParameters(GLES1State * state,GLenum pname,const GLfloat * params)2677 void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2678 {
2679 FogParameters &fog = state->fogParameters();
2680 switch (pname)
2681 {
2682 case GL_FOG_MODE:
2683 fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
2684 break;
2685 case GL_FOG_DENSITY:
2686 fog.density = params[0];
2687 break;
2688 case GL_FOG_START:
2689 fog.start = params[0];
2690 break;
2691 case GL_FOG_END:
2692 fog.end = params[0];
2693 break;
2694 case GL_FOG_COLOR:
2695 fog.color = ColorF::fromData(params);
2696 break;
2697 default:
2698 return;
2699 }
2700 }
2701
GetFogParameters(const GLES1State * state,GLenum pname,GLfloat * params)2702 void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2703 {
2704 const FogParameters &fog = state->fogParameters();
2705 switch (pname)
2706 {
2707 case GL_FOG_MODE:
2708 params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
2709 break;
2710 case GL_FOG_DENSITY:
2711 params[0] = fog.density;
2712 break;
2713 case GL_FOG_START:
2714 params[0] = fog.start;
2715 break;
2716 case GL_FOG_END:
2717 params[0] = fog.end;
2718 break;
2719 case GL_FOG_COLOR:
2720 fog.color.writeData(params);
2721 break;
2722 default:
2723 return;
2724 }
2725 }
2726
GetFogParameterCount(GLenum pname)2727 unsigned int GetFogParameterCount(GLenum pname)
2728 {
2729 switch (pname)
2730 {
2731 case GL_FOG_MODE:
2732 case GL_FOG_DENSITY:
2733 case GL_FOG_START:
2734 case GL_FOG_END:
2735 return 1;
2736 case GL_FOG_COLOR:
2737 return 4;
2738 default:
2739 return 0;
2740 }
2741 }
2742
GetTextureEnvParameterCount(TextureEnvParameter pname)2743 unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
2744 {
2745 switch (pname)
2746 {
2747 case TextureEnvParameter::Mode:
2748 case TextureEnvParameter::CombineRgb:
2749 case TextureEnvParameter::CombineAlpha:
2750 case TextureEnvParameter::Src0Rgb:
2751 case TextureEnvParameter::Src1Rgb:
2752 case TextureEnvParameter::Src2Rgb:
2753 case TextureEnvParameter::Src0Alpha:
2754 case TextureEnvParameter::Src1Alpha:
2755 case TextureEnvParameter::Src2Alpha:
2756 case TextureEnvParameter::Op0Rgb:
2757 case TextureEnvParameter::Op1Rgb:
2758 case TextureEnvParameter::Op2Rgb:
2759 case TextureEnvParameter::Op0Alpha:
2760 case TextureEnvParameter::Op1Alpha:
2761 case TextureEnvParameter::Op2Alpha:
2762 case TextureEnvParameter::RgbScale:
2763 case TextureEnvParameter::AlphaScale:
2764 case TextureEnvParameter::PointCoordReplace:
2765 return 1;
2766 case TextureEnvParameter::Color:
2767 return 4;
2768 default:
2769 return 0;
2770 }
2771 }
2772
ConvertTextureEnvFromInt(TextureEnvParameter pname,const GLint * input,GLfloat * output)2773 void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
2774 {
2775 if (IsTextureEnvEnumParameter(pname))
2776 {
2777 ConvertGLenumValue(input[0], output);
2778 return;
2779 }
2780
2781 switch (pname)
2782 {
2783 case TextureEnvParameter::RgbScale:
2784 case TextureEnvParameter::AlphaScale:
2785 output[0] = static_cast<GLfloat>(input[0]);
2786 break;
2787 case TextureEnvParameter::Color:
2788 for (int i = 0; i < 4; i++)
2789 {
2790 output[i] = input[i] / 255.0f;
2791 }
2792 break;
2793 default:
2794 UNREACHABLE();
2795 break;
2796 }
2797 }
2798
ConvertTextureEnvFromFixed(TextureEnvParameter pname,const GLfixed * input,GLfloat * output)2799 void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
2800 {
2801 if (IsTextureEnvEnumParameter(pname))
2802 {
2803 ConvertGLenumValue(input[0], output);
2804 return;
2805 }
2806
2807 switch (pname)
2808 {
2809 case TextureEnvParameter::RgbScale:
2810 case TextureEnvParameter::AlphaScale:
2811 output[0] = ConvertFixedToFloat(input[0]);
2812 break;
2813 case TextureEnvParameter::Color:
2814 for (int i = 0; i < 4; i++)
2815 {
2816 output[i] = ConvertFixedToFloat(input[i]);
2817 }
2818 break;
2819 default:
2820 UNREACHABLE();
2821 break;
2822 }
2823 }
2824
ConvertTextureEnvToInt(TextureEnvParameter pname,const GLfloat * input,GLint * output)2825 void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
2826 {
2827 if (IsTextureEnvEnumParameter(pname))
2828 {
2829 ConvertGLenumValue(input[0], output);
2830 return;
2831 }
2832
2833 switch (pname)
2834 {
2835 case TextureEnvParameter::RgbScale:
2836 case TextureEnvParameter::AlphaScale:
2837 output[0] = static_cast<GLint>(input[0]);
2838 break;
2839 case TextureEnvParameter::Color:
2840 for (int i = 0; i < 4; i++)
2841 {
2842 output[i] = static_cast<GLint>(input[i] * 255.0f);
2843 }
2844 break;
2845 default:
2846 UNREACHABLE();
2847 break;
2848 }
2849 }
2850
ConvertTextureEnvToFixed(TextureEnvParameter pname,const GLfloat * input,GLfixed * output)2851 void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
2852 {
2853 if (IsTextureEnvEnumParameter(pname))
2854 {
2855 ConvertGLenumValue(input[0], output);
2856 return;
2857 }
2858
2859 switch (pname)
2860 {
2861 case TextureEnvParameter::RgbScale:
2862 case TextureEnvParameter::AlphaScale:
2863 output[0] = ConvertFloatToFixed(input[0]);
2864 break;
2865 case TextureEnvParameter::Color:
2866 for (int i = 0; i < 4; i++)
2867 {
2868 output[i] = ConvertFloatToFixed(input[i]);
2869 }
2870 break;
2871 default:
2872 UNREACHABLE();
2873 break;
2874 }
2875 }
2876
SetTextureEnv(unsigned int unit,GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,const GLfloat * params)2877 void SetTextureEnv(unsigned int unit,
2878 GLES1State *state,
2879 TextureEnvTarget target,
2880 TextureEnvParameter pname,
2881 const GLfloat *params)
2882 {
2883 TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2884 GLenum asEnum = ConvertToGLenum(params[0]);
2885
2886 switch (target)
2887 {
2888 case TextureEnvTarget::Env:
2889 switch (pname)
2890 {
2891 case TextureEnvParameter::Mode:
2892 env.mode = FromGLenum<TextureEnvMode>(asEnum);
2893 break;
2894 case TextureEnvParameter::CombineRgb:
2895 env.combineRgb = FromGLenum<TextureCombine>(asEnum);
2896 break;
2897 case TextureEnvParameter::CombineAlpha:
2898 env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
2899 break;
2900 case TextureEnvParameter::Src0Rgb:
2901 env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
2902 break;
2903 case TextureEnvParameter::Src1Rgb:
2904 env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
2905 break;
2906 case TextureEnvParameter::Src2Rgb:
2907 env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
2908 break;
2909 case TextureEnvParameter::Src0Alpha:
2910 env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
2911 break;
2912 case TextureEnvParameter::Src1Alpha:
2913 env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
2914 break;
2915 case TextureEnvParameter::Src2Alpha:
2916 env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
2917 break;
2918 case TextureEnvParameter::Op0Rgb:
2919 env.op0Rgb = FromGLenum<TextureOp>(asEnum);
2920 break;
2921 case TextureEnvParameter::Op1Rgb:
2922 env.op1Rgb = FromGLenum<TextureOp>(asEnum);
2923 break;
2924 case TextureEnvParameter::Op2Rgb:
2925 env.op2Rgb = FromGLenum<TextureOp>(asEnum);
2926 break;
2927 case TextureEnvParameter::Op0Alpha:
2928 env.op0Alpha = FromGLenum<TextureOp>(asEnum);
2929 break;
2930 case TextureEnvParameter::Op1Alpha:
2931 env.op1Alpha = FromGLenum<TextureOp>(asEnum);
2932 break;
2933 case TextureEnvParameter::Op2Alpha:
2934 env.op2Alpha = FromGLenum<TextureOp>(asEnum);
2935 break;
2936 case TextureEnvParameter::Color:
2937 env.color = ColorF::fromData(params);
2938 break;
2939 case TextureEnvParameter::RgbScale:
2940 env.rgbScale = params[0];
2941 break;
2942 case TextureEnvParameter::AlphaScale:
2943 env.alphaScale = params[0];
2944 break;
2945 default:
2946 UNREACHABLE();
2947 break;
2948 }
2949 break;
2950 case TextureEnvTarget::PointSprite:
2951 switch (pname)
2952 {
2953 case TextureEnvParameter::PointCoordReplace:
2954 env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
2955 break;
2956 default:
2957 UNREACHABLE();
2958 break;
2959 }
2960 break;
2961 default:
2962 UNREACHABLE();
2963 break;
2964 }
2965 }
2966
GetTextureEnv(unsigned int unit,const GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,GLfloat * params)2967 void GetTextureEnv(unsigned int unit,
2968 const GLES1State *state,
2969 TextureEnvTarget target,
2970 TextureEnvParameter pname,
2971 GLfloat *params)
2972 {
2973 const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2974
2975 switch (target)
2976 {
2977 case TextureEnvTarget::Env:
2978 switch (pname)
2979 {
2980 case TextureEnvParameter::Mode:
2981 ConvertPackedEnum(env.mode, params);
2982 break;
2983 case TextureEnvParameter::CombineRgb:
2984 ConvertPackedEnum(env.combineRgb, params);
2985 break;
2986 case TextureEnvParameter::CombineAlpha:
2987 ConvertPackedEnum(env.combineAlpha, params);
2988 break;
2989 case TextureEnvParameter::Src0Rgb:
2990 ConvertPackedEnum(env.src0Rgb, params);
2991 break;
2992 case TextureEnvParameter::Src1Rgb:
2993 ConvertPackedEnum(env.src1Rgb, params);
2994 break;
2995 case TextureEnvParameter::Src2Rgb:
2996 ConvertPackedEnum(env.src2Rgb, params);
2997 break;
2998 case TextureEnvParameter::Src0Alpha:
2999 ConvertPackedEnum(env.src0Alpha, params);
3000 break;
3001 case TextureEnvParameter::Src1Alpha:
3002 ConvertPackedEnum(env.src1Alpha, params);
3003 break;
3004 case TextureEnvParameter::Src2Alpha:
3005 ConvertPackedEnum(env.src2Alpha, params);
3006 break;
3007 case TextureEnvParameter::Op0Rgb:
3008 ConvertPackedEnum(env.op0Rgb, params);
3009 break;
3010 case TextureEnvParameter::Op1Rgb:
3011 ConvertPackedEnum(env.op1Rgb, params);
3012 break;
3013 case TextureEnvParameter::Op2Rgb:
3014 ConvertPackedEnum(env.op2Rgb, params);
3015 break;
3016 case TextureEnvParameter::Op0Alpha:
3017 ConvertPackedEnum(env.op0Alpha, params);
3018 break;
3019 case TextureEnvParameter::Op1Alpha:
3020 ConvertPackedEnum(env.op1Alpha, params);
3021 break;
3022 case TextureEnvParameter::Op2Alpha:
3023 ConvertPackedEnum(env.op2Alpha, params);
3024 break;
3025 case TextureEnvParameter::Color:
3026 env.color.writeData(params);
3027 break;
3028 case TextureEnvParameter::RgbScale:
3029 *params = env.rgbScale;
3030 break;
3031 case TextureEnvParameter::AlphaScale:
3032 *params = env.alphaScale;
3033 break;
3034 default:
3035 UNREACHABLE();
3036 break;
3037 }
3038 break;
3039 case TextureEnvTarget::PointSprite:
3040 switch (pname)
3041 {
3042 case TextureEnvParameter::PointCoordReplace:
3043 *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
3044 break;
3045 default:
3046 UNREACHABLE();
3047 break;
3048 }
3049 break;
3050 default:
3051 UNREACHABLE();
3052 break;
3053 }
3054 }
3055
GetPointParameterCount(PointParameter pname)3056 unsigned int GetPointParameterCount(PointParameter pname)
3057 {
3058 switch (pname)
3059 {
3060 case PointParameter::PointSizeMin:
3061 case PointParameter::PointSizeMax:
3062 case PointParameter::PointFadeThresholdSize:
3063 return 1;
3064 case PointParameter::PointDistanceAttenuation:
3065 return 3;
3066 default:
3067 return 0;
3068 }
3069 }
3070
SetPointParameter(GLES1State * state,PointParameter pname,const GLfloat * params)3071 void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
3072 {
3073
3074 PointParameters &pointParams = state->pointParameters();
3075
3076 switch (pname)
3077 {
3078 case PointParameter::PointSizeMin:
3079 pointParams.pointSizeMin = params[0];
3080 break;
3081 case PointParameter::PointSizeMax:
3082 pointParams.pointSizeMax = params[0];
3083 break;
3084 case PointParameter::PointFadeThresholdSize:
3085 pointParams.pointFadeThresholdSize = params[0];
3086 break;
3087 case PointParameter::PointDistanceAttenuation:
3088 for (unsigned int i = 0; i < 3; i++)
3089 {
3090 pointParams.pointDistanceAttenuation[i] = params[i];
3091 }
3092 break;
3093 default:
3094 UNREACHABLE();
3095 }
3096 }
3097
GetPointParameter(const GLES1State * state,PointParameter pname,GLfloat * params)3098 void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
3099 {
3100 const PointParameters &pointParams = state->pointParameters();
3101
3102 switch (pname)
3103 {
3104 case PointParameter::PointSizeMin:
3105 params[0] = pointParams.pointSizeMin;
3106 break;
3107 case PointParameter::PointSizeMax:
3108 params[0] = pointParams.pointSizeMax;
3109 break;
3110 case PointParameter::PointFadeThresholdSize:
3111 params[0] = pointParams.pointFadeThresholdSize;
3112 break;
3113 case PointParameter::PointDistanceAttenuation:
3114 for (unsigned int i = 0; i < 3; i++)
3115 {
3116 params[i] = pointParams.pointDistanceAttenuation[i];
3117 }
3118 break;
3119 default:
3120 UNREACHABLE();
3121 }
3122 }
3123
SetPointSize(GLES1State * state,GLfloat size)3124 void SetPointSize(GLES1State *state, GLfloat size)
3125 {
3126 PointParameters ¶ms = state->pointParameters();
3127 params.pointSize = size;
3128 }
3129
GetPointSize(const GLES1State * state,GLfloat * sizeOut)3130 void GetPointSize(const GLES1State *state, GLfloat *sizeOut)
3131 {
3132 const PointParameters ¶ms = state->pointParameters();
3133 *sizeOut = params.pointSize;
3134 }
3135
GetTexParameterCount(GLenum pname)3136 unsigned int GetTexParameterCount(GLenum pname)
3137 {
3138 switch (pname)
3139 {
3140 case GL_TEXTURE_CROP_RECT_OES:
3141 case GL_TEXTURE_BORDER_COLOR:
3142 return 4;
3143 case GL_TEXTURE_MAG_FILTER:
3144 case GL_TEXTURE_MIN_FILTER:
3145 case GL_TEXTURE_WRAP_S:
3146 case GL_TEXTURE_WRAP_T:
3147 case GL_TEXTURE_USAGE_ANGLE:
3148 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3149 case GL_TEXTURE_IMMUTABLE_FORMAT:
3150 case GL_TEXTURE_WRAP_R:
3151 case GL_TEXTURE_IMMUTABLE_LEVELS:
3152 case GL_TEXTURE_SWIZZLE_R:
3153 case GL_TEXTURE_SWIZZLE_G:
3154 case GL_TEXTURE_SWIZZLE_B:
3155 case GL_TEXTURE_SWIZZLE_A:
3156 case GL_TEXTURE_BASE_LEVEL:
3157 case GL_TEXTURE_MAX_LEVEL:
3158 case GL_TEXTURE_MIN_LOD:
3159 case GL_TEXTURE_MAX_LOD:
3160 case GL_TEXTURE_COMPARE_MODE:
3161 case GL_TEXTURE_COMPARE_FUNC:
3162 case GL_TEXTURE_SRGB_DECODE_EXT:
3163 case GL_DEPTH_STENCIL_TEXTURE_MODE:
3164 case GL_TEXTURE_NATIVE_ID_ANGLE:
3165 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3166 case GL_RENDERABILITY_VALIDATION_ANGLE:
3167 return 1;
3168 default:
3169 return 0;
3170 }
3171 }
3172
GetQueryParameterInfo(const State & glState,GLenum pname,GLenum * type,unsigned int * numParams)3173 bool GetQueryParameterInfo(const State &glState,
3174 GLenum pname,
3175 GLenum *type,
3176 unsigned int *numParams)
3177 {
3178 const Caps &caps = glState.getCaps();
3179 const Extensions &extensions = glState.getExtensions();
3180 GLint clientMajorVersion = glState.getClientMajorVersion();
3181 EGLenum clientType = glState.getClientType();
3182
3183 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
3184 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
3185 // to the fact that it is stored internally as a float, and so would require conversion
3186 // if returned from Context::getIntegerv. Since this conversion is already implemented
3187 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
3188 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
3189 // application.
3190 switch (pname)
3191 {
3192 case GL_COMPRESSED_TEXTURE_FORMATS:
3193 {
3194 *type = GL_INT;
3195 *numParams = static_cast<unsigned int>(caps.compressedTextureFormats.size());
3196 return true;
3197 }
3198 case GL_SHADER_BINARY_FORMATS:
3199 {
3200 *type = GL_INT;
3201 *numParams = static_cast<unsigned int>(caps.shaderBinaryFormats.size());
3202 return true;
3203 }
3204
3205 case GL_MAX_VERTEX_ATTRIBS:
3206 case GL_MAX_VERTEX_UNIFORM_VECTORS:
3207 case GL_MAX_VARYING_VECTORS:
3208 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
3209 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
3210 case GL_MAX_TEXTURE_IMAGE_UNITS:
3211 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3212 case GL_MAX_RENDERBUFFER_SIZE:
3213 case GL_NUM_SHADER_BINARY_FORMATS:
3214 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3215 case GL_ARRAY_BUFFER_BINDING:
3216 case GL_FRAMEBUFFER_BINDING: // GL_FRAMEBUFFER_BINDING now equivalent to
3217 // GL_DRAW_FRAMEBUFFER_BINDING
3218 case GL_RENDERBUFFER_BINDING:
3219 case GL_CURRENT_PROGRAM:
3220 case GL_PACK_ALIGNMENT:
3221 case GL_UNPACK_ALIGNMENT:
3222 case GL_GENERATE_MIPMAP_HINT:
3223 case GL_RED_BITS:
3224 case GL_GREEN_BITS:
3225 case GL_BLUE_BITS:
3226 case GL_ALPHA_BITS:
3227 case GL_DEPTH_BITS:
3228 case GL_STENCIL_BITS:
3229 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3230 case GL_CULL_FACE_MODE:
3231 case GL_FRONT_FACE:
3232 case GL_ACTIVE_TEXTURE:
3233 case GL_STENCIL_FUNC:
3234 case GL_STENCIL_VALUE_MASK:
3235 case GL_STENCIL_REF:
3236 case GL_STENCIL_FAIL:
3237 case GL_STENCIL_PASS_DEPTH_FAIL:
3238 case GL_STENCIL_PASS_DEPTH_PASS:
3239 case GL_STENCIL_BACK_FUNC:
3240 case GL_STENCIL_BACK_VALUE_MASK:
3241 case GL_STENCIL_BACK_REF:
3242 case GL_STENCIL_BACK_FAIL:
3243 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
3244 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
3245 case GL_DEPTH_FUNC:
3246 case GL_BLEND_SRC_RGB:
3247 case GL_BLEND_SRC_ALPHA:
3248 case GL_BLEND_DST_RGB:
3249 case GL_BLEND_DST_ALPHA:
3250 case GL_BLEND_EQUATION_RGB:
3251 case GL_BLEND_EQUATION_ALPHA:
3252 case GL_STENCIL_WRITEMASK:
3253 case GL_STENCIL_BACK_WRITEMASK:
3254 case GL_STENCIL_CLEAR_VALUE:
3255 case GL_SUBPIXEL_BITS:
3256 case GL_MAX_TEXTURE_SIZE:
3257 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3258 case GL_SAMPLE_BUFFERS:
3259 case GL_SAMPLES:
3260 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3261 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3262 case GL_TEXTURE_BINDING_2D:
3263 case GL_TEXTURE_BINDING_CUBE_MAP:
3264 case GL_RESET_NOTIFICATION_STRATEGY_EXT:
3265 case GL_QUERY_COUNTER_BITS_EXT:
3266 {
3267 *type = GL_INT;
3268 *numParams = 1;
3269 return true;
3270 }
3271 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
3272 {
3273 if (!extensions.packReverseRowOrderANGLE)
3274 {
3275 return false;
3276 }
3277 *type = GL_INT;
3278 *numParams = 1;
3279 return true;
3280 }
3281 case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
3282 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
3283 {
3284 if (!extensions.textureRectangleANGLE)
3285 {
3286 return false;
3287 }
3288 *type = GL_INT;
3289 *numParams = 1;
3290 return true;
3291 }
3292 case GL_MAX_DRAW_BUFFERS_EXT:
3293 case GL_MAX_COLOR_ATTACHMENTS_EXT:
3294 {
3295 if ((clientMajorVersion < 3) && !extensions.drawBuffersEXT)
3296 {
3297 return false;
3298 }
3299 *type = GL_INT;
3300 *numParams = 1;
3301 return true;
3302 }
3303 case GL_MAX_VIEWPORT_DIMS:
3304 {
3305 *type = GL_INT;
3306 *numParams = 2;
3307 return true;
3308 }
3309 case GL_VIEWPORT:
3310 case GL_SCISSOR_BOX:
3311 {
3312 *type = GL_INT;
3313 *numParams = 4;
3314 return true;
3315 }
3316 case GL_SHADER_COMPILER:
3317 case GL_SAMPLE_COVERAGE_INVERT:
3318 case GL_DEPTH_WRITEMASK:
3319 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
3320 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
3321 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as
3322 // bool-natural
3323 case GL_SAMPLE_COVERAGE:
3324 case GL_SCISSOR_TEST:
3325 case GL_STENCIL_TEST:
3326 case GL_DEPTH_TEST:
3327 case GL_BLEND:
3328 case GL_DITHER:
3329 case GL_CONTEXT_ROBUST_ACCESS_EXT:
3330 {
3331 *type = GL_BOOL;
3332 *numParams = 1;
3333 return true;
3334 }
3335 case GL_POLYGON_OFFSET_POINT_NV:
3336 {
3337 if (!extensions.polygonModeNV)
3338 {
3339 return false;
3340 }
3341 *type = GL_BOOL;
3342 *numParams = 1;
3343 return true;
3344 }
3345 case GL_POLYGON_OFFSET_LINE_NV: // = GL_POLYGON_OFFSET_LINE_ANGLE
3346 {
3347 if (!extensions.polygonModeAny())
3348 {
3349 return false;
3350 }
3351 *type = GL_BOOL;
3352 *numParams = 1;
3353 return true;
3354 }
3355 case GL_DEPTH_CLAMP_EXT:
3356 {
3357 if (!extensions.depthClampEXT)
3358 {
3359 return false;
3360 }
3361 *type = GL_BOOL;
3362 *numParams = 1;
3363 return true;
3364 }
3365 case GL_COLOR_LOGIC_OP:
3366 {
3367 if (clientMajorVersion == 1)
3368 {
3369 // Handle logicOp in GLES1 through GLES1 state management.
3370 break;
3371 }
3372
3373 if (!extensions.logicOpANGLE)
3374 {
3375 return false;
3376 }
3377 *type = GL_BOOL;
3378 *numParams = 1;
3379 return true;
3380 }
3381 case GL_COLOR_WRITEMASK:
3382 {
3383 *type = GL_BOOL;
3384 *numParams = 4;
3385 return true;
3386 }
3387 case GL_POLYGON_OFFSET_FACTOR:
3388 case GL_POLYGON_OFFSET_UNITS:
3389 case GL_SAMPLE_COVERAGE_VALUE:
3390 case GL_DEPTH_CLEAR_VALUE:
3391 case GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY:
3392 case GL_LINE_WIDTH:
3393 {
3394 *type = GL_FLOAT;
3395 *numParams = 1;
3396 return true;
3397 }
3398 case GL_POLYGON_OFFSET_CLAMP_EXT:
3399 if (!extensions.polygonOffsetClampEXT)
3400 {
3401 return false;
3402 }
3403 *type = GL_FLOAT;
3404 *numParams = 1;
3405 return true;
3406 case GL_ALIASED_LINE_WIDTH_RANGE:
3407 case GL_MULTISAMPLE_LINE_WIDTH_RANGE:
3408 case GL_ALIASED_POINT_SIZE_RANGE:
3409 case GL_DEPTH_RANGE:
3410 {
3411 *type = GL_FLOAT;
3412 *numParams = 2;
3413 return true;
3414 }
3415 case GL_COLOR_CLEAR_VALUE:
3416 case GL_BLEND_COLOR:
3417 {
3418 *type = GL_FLOAT;
3419 *numParams = 4;
3420 return true;
3421 }
3422 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
3423 if (!extensions.textureFilterAnisotropicEXT)
3424 {
3425 return false;
3426 }
3427 *type = GL_FLOAT;
3428 *numParams = 1;
3429 return true;
3430 case GL_TIMESTAMP_EXT:
3431 if (!extensions.disjointTimerQueryEXT)
3432 {
3433 return false;
3434 }
3435 *type = GL_INT_64_ANGLEX;
3436 *numParams = 1;
3437 return true;
3438 case GL_GPU_DISJOINT_EXT:
3439 if (!extensions.disjointTimerQueryEXT)
3440 {
3441 return false;
3442 }
3443 *type = GL_INT;
3444 *numParams = 1;
3445 return true;
3446 case GL_COVERAGE_MODULATION_CHROMIUM:
3447 if (!extensions.framebufferMixedSamplesCHROMIUM)
3448 {
3449 return false;
3450 }
3451 *type = GL_INT;
3452 *numParams = 1;
3453 return true;
3454 case GL_TEXTURE_BINDING_EXTERNAL_OES:
3455 if (!extensions.EGLStreamConsumerExternalNV && !extensions.EGLImageExternalOES)
3456 {
3457 return false;
3458 }
3459 *type = GL_INT;
3460 *numParams = 1;
3461 return true;
3462 case GL_MAX_CLIP_DISTANCES_EXT: // case GL_MAX_CLIP_PLANES
3463 case GL_CLIP_DISTANCE0_EXT:
3464 case GL_CLIP_DISTANCE1_EXT:
3465 case GL_CLIP_DISTANCE2_EXT:
3466 case GL_CLIP_DISTANCE3_EXT:
3467 case GL_CLIP_DISTANCE4_EXT:
3468 case GL_CLIP_DISTANCE5_EXT:
3469 case GL_CLIP_DISTANCE6_EXT:
3470 case GL_CLIP_DISTANCE7_EXT:
3471 if (clientMajorVersion < 2)
3472 {
3473 break;
3474 }
3475 if (!extensions.clipDistanceAPPLE && !extensions.clipCullDistanceAny())
3476 {
3477 // NOTE(hqle): if client version is 1. GL_MAX_CLIP_DISTANCES_EXT is equal
3478 // to GL_MAX_CLIP_PLANES which is a valid enum.
3479 return false;
3480 }
3481 *type = (pname == GL_MAX_CLIP_DISTANCES_EXT) ? GL_INT : GL_BOOL;
3482 *numParams = 1;
3483 return true;
3484 case GL_MAX_CULL_DISTANCES_EXT:
3485 case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
3486 if (!extensions.clipCullDistanceAny())
3487 {
3488 return false;
3489 }
3490 *type = GL_INT;
3491 *numParams = 1;
3492 return true;
3493 case GL_CLIP_ORIGIN_EXT:
3494 case GL_CLIP_DEPTH_MODE_EXT:
3495 if (!extensions.clipControlEXT)
3496 {
3497 return false;
3498 }
3499 *type = GL_INT;
3500 *numParams = 1;
3501 return true;
3502 case GL_POLYGON_MODE_NV: // = GL_POLYGON_MODE_ANGLE
3503 {
3504 if (!extensions.polygonModeAny())
3505 {
3506 return false;
3507 }
3508 *type = GL_INT;
3509 *numParams = 1;
3510 return true;
3511 }
3512 case GL_PRIMITIVE_BOUNDING_BOX:
3513 if (!extensions.primitiveBoundingBoxAny())
3514 {
3515 return false;
3516 }
3517 *type = GL_FLOAT;
3518 *numParams = 8;
3519 return true;
3520 case GL_SHADING_RATE_QCOM:
3521 if (!extensions.shadingRateQCOM)
3522 {
3523 return false;
3524 }
3525 *type = GL_INT;
3526 *numParams = 1;
3527 return true;
3528 }
3529
3530 if (clientType == EGL_OPENGL_API ||
3531 (clientType == EGL_OPENGL_ES_API && glState.getClientVersion() >= Version(3, 2)))
3532 {
3533 switch (pname)
3534 {
3535 case GL_CONTEXT_FLAGS:
3536 {
3537 *type = GL_INT;
3538 *numParams = 1;
3539 return true;
3540 }
3541 }
3542 }
3543
3544 if (clientType == EGL_OPENGL_API)
3545 {
3546 switch (pname)
3547 {
3548 case GL_CONTEXT_PROFILE_MASK:
3549 {
3550 *type = GL_INT;
3551 *numParams = 1;
3552 return true;
3553 }
3554 }
3555 }
3556
3557 if (extensions.debugKHR)
3558 {
3559 switch (pname)
3560 {
3561 case GL_DEBUG_LOGGED_MESSAGES:
3562 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
3563 case GL_DEBUG_GROUP_STACK_DEPTH:
3564 case GL_MAX_DEBUG_MESSAGE_LENGTH:
3565 case GL_MAX_DEBUG_LOGGED_MESSAGES:
3566 case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
3567 case GL_MAX_LABEL_LENGTH:
3568 *type = GL_INT;
3569 *numParams = 1;
3570 return true;
3571
3572 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
3573 case GL_DEBUG_OUTPUT:
3574 *type = GL_BOOL;
3575 *numParams = 1;
3576 return true;
3577 }
3578 }
3579
3580 if (extensions.multisampleCompatibilityEXT)
3581 {
3582 switch (pname)
3583 {
3584 case GL_MULTISAMPLE_EXT:
3585 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3586 *type = GL_BOOL;
3587 *numParams = 1;
3588 return true;
3589 }
3590 }
3591
3592 if (extensions.bindGeneratesResourceCHROMIUM)
3593 {
3594 switch (pname)
3595 {
3596 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
3597 *type = GL_BOOL;
3598 *numParams = 1;
3599 return true;
3600 }
3601 }
3602
3603 if (extensions.clientArraysANGLE)
3604 {
3605 switch (pname)
3606 {
3607 case GL_CLIENT_ARRAYS_ANGLE:
3608 *type = GL_BOOL;
3609 *numParams = 1;
3610 return true;
3611 }
3612 }
3613
3614 if (extensions.sRGBWriteControlEXT)
3615 {
3616 switch (pname)
3617 {
3618 case GL_FRAMEBUFFER_SRGB_EXT:
3619 *type = GL_BOOL;
3620 *numParams = 1;
3621 return true;
3622 }
3623 }
3624
3625 if (extensions.robustResourceInitializationANGLE &&
3626 pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
3627 {
3628 *type = GL_BOOL;
3629 *numParams = 1;
3630 return true;
3631 }
3632
3633 if (extensions.programCacheControlANGLE && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
3634 {
3635 *type = GL_BOOL;
3636 *numParams = 1;
3637 return true;
3638 }
3639
3640 if (extensions.parallelShaderCompileKHR && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR)
3641 {
3642 *type = GL_INT;
3643 *numParams = 1;
3644 return true;
3645 }
3646
3647 if (extensions.blendFuncExtendedEXT && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT)
3648 {
3649 *type = GL_INT;
3650 *numParams = 1;
3651 return true;
3652 }
3653
3654 if (extensions.robustFragmentShaderOutputANGLE &&
3655 pname == GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE)
3656 {
3657 *type = GL_BOOL;
3658 *numParams = 1;
3659 return true;
3660 }
3661
3662 // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
3663 switch (pname)
3664 {
3665 // GL_DRAW_FRAMEBUFFER_BINDING equivalent to GL_FRAMEBUFFER_BINDING
3666 case GL_READ_FRAMEBUFFER_BINDING:
3667 if ((clientMajorVersion < 3) && !extensions.framebufferBlitAny())
3668 {
3669 return false;
3670 }
3671 *type = GL_INT;
3672 *numParams = 1;
3673 return true;
3674
3675 case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
3676 if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3677 {
3678 return false;
3679 }
3680 *type = GL_INT;
3681 *numParams = 1;
3682 return true;
3683
3684 case GL_PROGRAM_BINARY_FORMATS_OES:
3685 if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3686 {
3687 return false;
3688 }
3689 *type = GL_INT;
3690 *numParams = static_cast<unsigned int>(caps.programBinaryFormats.size());
3691 return true;
3692
3693 case GL_PACK_ROW_LENGTH:
3694 case GL_PACK_SKIP_ROWS:
3695 case GL_PACK_SKIP_PIXELS:
3696 if ((clientMajorVersion < 3) && !extensions.packSubimageNV)
3697 {
3698 return false;
3699 }
3700 *type = GL_INT;
3701 *numParams = 1;
3702 return true;
3703 case GL_UNPACK_ROW_LENGTH:
3704 case GL_UNPACK_SKIP_ROWS:
3705 case GL_UNPACK_SKIP_PIXELS:
3706 if ((clientMajorVersion < 3) && !extensions.unpackSubimageEXT)
3707 {
3708 return false;
3709 }
3710 *type = GL_INT;
3711 *numParams = 1;
3712 return true;
3713 case GL_VERTEX_ARRAY_BINDING:
3714 if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES)
3715 {
3716 return false;
3717 }
3718 *type = GL_INT;
3719 *numParams = 1;
3720 return true;
3721 case GL_PIXEL_PACK_BUFFER_BINDING:
3722 case GL_PIXEL_UNPACK_BUFFER_BINDING:
3723 if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV)
3724 {
3725 return false;
3726 }
3727 *type = GL_INT;
3728 *numParams = 1;
3729 return true;
3730 case GL_MAX_SAMPLES:
3731 {
3732 static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
3733 "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
3734 if ((clientMajorVersion < 3) && !(extensions.framebufferMultisampleANGLE ||
3735 extensions.multisampledRenderToTextureEXT))
3736 {
3737 return false;
3738 }
3739 *type = GL_INT;
3740 *numParams = 1;
3741 return true;
3742
3743 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
3744 if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES)
3745 {
3746 return false;
3747 }
3748 *type = GL_INT;
3749 *numParams = 1;
3750 return true;
3751 }
3752 case GL_TEXTURE_BINDING_3D:
3753 if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3754 {
3755 return false;
3756 }
3757 *type = GL_INT;
3758 *numParams = 1;
3759 return true;
3760 case GL_MAX_3D_TEXTURE_SIZE:
3761 if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3762 {
3763 return false;
3764 }
3765 *type = GL_INT;
3766 *numParams = 1;
3767 return true;
3768 }
3769
3770 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
3771 {
3772 if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffersEXT)
3773 {
3774 return false;
3775 }
3776 *type = GL_INT;
3777 *numParams = 1;
3778 return true;
3779 }
3780
3781 if ((extensions.multiview2OVR || extensions.multiviewOVR) && pname == GL_MAX_VIEWS_OVR)
3782 {
3783 *type = GL_INT;
3784 *numParams = 1;
3785 return true;
3786 }
3787
3788 if (extensions.provokingVertexANGLE && pname == GL_PROVOKING_VERTEX_ANGLE)
3789 {
3790 *type = GL_INT;
3791 *numParams = 1;
3792 return true;
3793 }
3794
3795 if (extensions.shaderFramebufferFetchARM &&
3796 (pname == GL_FETCH_PER_SAMPLE_ARM || pname == GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM))
3797 {
3798 *type = GL_BOOL;
3799 *numParams = 1;
3800 return true;
3801 }
3802
3803 if (glState.getClientVersion() < Version(2, 0))
3804 {
3805 switch (pname)
3806 {
3807 case GL_ALPHA_TEST_FUNC:
3808 case GL_CLIENT_ACTIVE_TEXTURE:
3809 case GL_MATRIX_MODE:
3810 case GL_MAX_TEXTURE_UNITS:
3811 case GL_MAX_MODELVIEW_STACK_DEPTH:
3812 case GL_MAX_PROJECTION_STACK_DEPTH:
3813 case GL_MAX_TEXTURE_STACK_DEPTH:
3814 case GL_MAX_LIGHTS:
3815 case GL_MAX_CLIP_PLANES:
3816 case GL_VERTEX_ARRAY_STRIDE:
3817 case GL_NORMAL_ARRAY_STRIDE:
3818 case GL_COLOR_ARRAY_STRIDE:
3819 case GL_TEXTURE_COORD_ARRAY_STRIDE:
3820 case GL_VERTEX_ARRAY_SIZE:
3821 case GL_COLOR_ARRAY_SIZE:
3822 case GL_TEXTURE_COORD_ARRAY_SIZE:
3823 case GL_VERTEX_ARRAY_TYPE:
3824 case GL_NORMAL_ARRAY_TYPE:
3825 case GL_COLOR_ARRAY_TYPE:
3826 case GL_TEXTURE_COORD_ARRAY_TYPE:
3827 case GL_VERTEX_ARRAY_BUFFER_BINDING:
3828 case GL_NORMAL_ARRAY_BUFFER_BINDING:
3829 case GL_COLOR_ARRAY_BUFFER_BINDING:
3830 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
3831 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
3832 case GL_POINT_SIZE_ARRAY_TYPE_OES:
3833 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
3834 case GL_SHADE_MODEL:
3835 case GL_MODELVIEW_STACK_DEPTH:
3836 case GL_PROJECTION_STACK_DEPTH:
3837 case GL_TEXTURE_STACK_DEPTH:
3838 case GL_LOGIC_OP_MODE:
3839 case GL_BLEND_SRC:
3840 case GL_BLEND_DST:
3841 case GL_PERSPECTIVE_CORRECTION_HINT:
3842 case GL_POINT_SMOOTH_HINT:
3843 case GL_LINE_SMOOTH_HINT:
3844 case GL_FOG_HINT:
3845 *type = GL_INT;
3846 *numParams = 1;
3847 return true;
3848 case GL_ALPHA_TEST_REF:
3849 case GL_FOG_DENSITY:
3850 case GL_FOG_START:
3851 case GL_FOG_END:
3852 case GL_FOG_MODE:
3853 case GL_POINT_SIZE:
3854 case GL_POINT_SIZE_MIN:
3855 case GL_POINT_SIZE_MAX:
3856 case GL_POINT_FADE_THRESHOLD_SIZE:
3857 *type = GL_FLOAT;
3858 *numParams = 1;
3859 return true;
3860 case GL_SMOOTH_POINT_SIZE_RANGE:
3861 case GL_SMOOTH_LINE_WIDTH_RANGE:
3862 *type = GL_FLOAT;
3863 *numParams = 2;
3864 return true;
3865 case GL_CURRENT_COLOR:
3866 case GL_CURRENT_TEXTURE_COORDS:
3867 case GL_LIGHT_MODEL_AMBIENT:
3868 case GL_FOG_COLOR:
3869 *type = GL_FLOAT;
3870 *numParams = 4;
3871 return true;
3872 case GL_CURRENT_NORMAL:
3873 case GL_POINT_DISTANCE_ATTENUATION:
3874 *type = GL_FLOAT;
3875 *numParams = 3;
3876 return true;
3877 case GL_MODELVIEW_MATRIX:
3878 case GL_PROJECTION_MATRIX:
3879 case GL_TEXTURE_MATRIX:
3880 *type = GL_FLOAT;
3881 *numParams = 16;
3882 return true;
3883 case GL_ALPHA_TEST:
3884 case GL_CLIP_PLANE0:
3885 case GL_CLIP_PLANE1:
3886 case GL_CLIP_PLANE2:
3887 case GL_CLIP_PLANE3:
3888 case GL_CLIP_PLANE4:
3889 case GL_CLIP_PLANE5:
3890 case GL_COLOR_ARRAY:
3891 case GL_COLOR_LOGIC_OP:
3892 case GL_COLOR_MATERIAL:
3893 case GL_FOG:
3894 case GL_LIGHT_MODEL_TWO_SIDE:
3895 case GL_LIGHT0:
3896 case GL_LIGHT1:
3897 case GL_LIGHT2:
3898 case GL_LIGHT3:
3899 case GL_LIGHT4:
3900 case GL_LIGHT5:
3901 case GL_LIGHT6:
3902 case GL_LIGHT7:
3903 case GL_LIGHTING:
3904 case GL_LINE_SMOOTH:
3905 case GL_NORMAL_ARRAY:
3906 case GL_NORMALIZE:
3907 case GL_POINT_SIZE_ARRAY_OES:
3908 case GL_POINT_SMOOTH:
3909 case GL_POINT_SPRITE_OES:
3910 case GL_RESCALE_NORMAL:
3911 case GL_TEXTURE_2D:
3912 case GL_TEXTURE_CUBE_MAP:
3913 case GL_TEXTURE_COORD_ARRAY:
3914 case GL_VERTEX_ARRAY:
3915 *type = GL_BOOL;
3916 *numParams = 1;
3917 return true;
3918 }
3919 }
3920
3921 if (glState.getClientVersion() < Version(3, 0))
3922 {
3923 return false;
3924 }
3925
3926 // Check for ES3.0+ parameter names
3927 switch (pname)
3928 {
3929 case GL_MAX_UNIFORM_BUFFER_BINDINGS:
3930 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
3931 case GL_UNIFORM_BUFFER_BINDING:
3932 case GL_TRANSFORM_FEEDBACK_BINDING:
3933 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3934 case GL_COPY_READ_BUFFER_BINDING:
3935 case GL_COPY_WRITE_BUFFER_BINDING:
3936 case GL_SAMPLER_BINDING:
3937 case GL_READ_BUFFER:
3938 case GL_TEXTURE_BINDING_3D:
3939 case GL_TEXTURE_BINDING_2D_ARRAY:
3940 case GL_MAX_ARRAY_TEXTURE_LAYERS:
3941 case GL_MAX_VERTEX_UNIFORM_BLOCKS:
3942 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
3943 case GL_MAX_COMBINED_UNIFORM_BLOCKS:
3944 case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
3945 case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
3946 case GL_MAX_VARYING_COMPONENTS:
3947 case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
3948 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
3949 case GL_MIN_PROGRAM_TEXEL_OFFSET:
3950 case GL_MAX_PROGRAM_TEXEL_OFFSET:
3951 case GL_NUM_EXTENSIONS:
3952 case GL_MAJOR_VERSION:
3953 case GL_MINOR_VERSION:
3954 case GL_MAX_ELEMENTS_INDICES:
3955 case GL_MAX_ELEMENTS_VERTICES:
3956 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
3957 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
3958 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
3959 case GL_UNPACK_IMAGE_HEIGHT:
3960 case GL_UNPACK_SKIP_IMAGES:
3961 {
3962 *type = GL_INT;
3963 *numParams = 1;
3964 return true;
3965 }
3966
3967 case GL_MAX_ELEMENT_INDEX:
3968 case GL_MAX_UNIFORM_BLOCK_SIZE:
3969 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
3970 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
3971 case GL_MAX_SERVER_WAIT_TIMEOUT:
3972 {
3973 *type = GL_INT_64_ANGLEX;
3974 *numParams = 1;
3975 return true;
3976 }
3977
3978 case GL_TRANSFORM_FEEDBACK_ACTIVE:
3979 case GL_TRANSFORM_FEEDBACK_PAUSED:
3980 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
3981 case GL_RASTERIZER_DISCARD:
3982 {
3983 *type = GL_BOOL;
3984 *numParams = 1;
3985 return true;
3986 }
3987
3988 case GL_MAX_TEXTURE_LOD_BIAS:
3989 {
3990 *type = GL_FLOAT;
3991 *numParams = 1;
3992 return true;
3993 }
3994 }
3995
3996 if (extensions.shaderMultisampleInterpolationOES)
3997 {
3998 switch (pname)
3999 {
4000 case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES:
4001 case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES:
4002 {
4003 *type = GL_FLOAT;
4004 *numParams = 1;
4005 return true;
4006 }
4007 case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
4008 {
4009 *type = GL_INT;
4010 *numParams = 1;
4011 return true;
4012 }
4013 }
4014 }
4015
4016 if (extensions.requestExtensionANGLE)
4017 {
4018 switch (pname)
4019 {
4020 case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
4021 *type = GL_INT;
4022 *numParams = 1;
4023 return true;
4024 }
4025 }
4026
4027 if (extensions.textureMultisampleANGLE)
4028 {
4029 switch (pname)
4030 {
4031 case GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE:
4032 case GL_MAX_INTEGER_SAMPLES_ANGLE:
4033 case GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE:
4034 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE:
4035 case GL_MAX_SAMPLE_MASK_WORDS:
4036 *type = GL_INT;
4037 *numParams = 1;
4038 return true;
4039 }
4040 }
4041
4042 if (extensions.textureCubeMapArrayAny())
4043 {
4044 switch (pname)
4045 {
4046 case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
4047 *type = GL_INT;
4048 *numParams = 1;
4049 return true;
4050 }
4051 }
4052
4053 if (extensions.textureBufferAny())
4054 {
4055 switch (pname)
4056 {
4057 case GL_TEXTURE_BUFFER_BINDING:
4058 case GL_TEXTURE_BINDING_BUFFER:
4059 case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
4060 case GL_MAX_TEXTURE_BUFFER_SIZE:
4061 *type = GL_INT;
4062 *numParams = 1;
4063 return true;
4064 }
4065 }
4066
4067 if (extensions.shaderPixelLocalStorageANGLE)
4068 {
4069 switch (pname)
4070 {
4071 case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
4072 case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE:
4073 case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
4074 case GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE:
4075 *type = GL_INT;
4076 *numParams = 1;
4077 return true;
4078 }
4079 }
4080
4081 if (glState.getClientVersion() < Version(3, 1))
4082 {
4083 return false;
4084 }
4085
4086 // Check for ES3.1+ parameter names
4087 switch (pname)
4088 {
4089 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
4090 case GL_DRAW_INDIRECT_BUFFER_BINDING:
4091 case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
4092 case GL_MAX_FRAMEBUFFER_WIDTH:
4093 case GL_MAX_FRAMEBUFFER_HEIGHT:
4094 case GL_MAX_FRAMEBUFFER_SAMPLES:
4095 case GL_MAX_SAMPLE_MASK_WORDS:
4096 case GL_MAX_COLOR_TEXTURE_SAMPLES:
4097 case GL_MAX_DEPTH_TEXTURE_SAMPLES:
4098 case GL_MAX_INTEGER_SAMPLES:
4099 case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
4100 case GL_MAX_VERTEX_ATTRIB_BINDINGS:
4101 case GL_MAX_VERTEX_ATTRIB_STRIDE:
4102 case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
4103 case GL_MAX_VERTEX_ATOMIC_COUNTERS:
4104 case GL_MAX_VERTEX_IMAGE_UNIFORMS:
4105 case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
4106 case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
4107 case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
4108 case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
4109 case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
4110 case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
4111 case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
4112 case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
4113 case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
4114 case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
4115 case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
4116 case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
4117 case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
4118 case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
4119 case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
4120 case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
4121 case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
4122 case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
4123 case GL_MAX_UNIFORM_LOCATIONS:
4124 case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
4125 case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
4126 case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
4127 case GL_MAX_COMBINED_ATOMIC_COUNTERS:
4128 case GL_MAX_IMAGE_UNITS:
4129 case GL_MAX_COMBINED_IMAGE_UNIFORMS:
4130 case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
4131 case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
4132 case GL_SHADER_STORAGE_BUFFER_BINDING:
4133 case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
4134 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
4135 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
4136 case GL_PROGRAM_PIPELINE_BINDING:
4137 *type = GL_INT;
4138 *numParams = 1;
4139 return true;
4140 case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
4141 *type = GL_INT_64_ANGLEX;
4142 *numParams = 1;
4143 return true;
4144 case GL_SAMPLE_MASK:
4145 case GL_SAMPLE_SHADING:
4146 *type = GL_BOOL;
4147 *numParams = 1;
4148 return true;
4149 case GL_MIN_SAMPLE_SHADING_VALUE:
4150 *type = GL_FLOAT;
4151 *numParams = 1;
4152 return true;
4153 }
4154
4155 if (extensions.geometryShaderAny())
4156 {
4157 switch (pname)
4158 {
4159 case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
4160 case GL_LAYER_PROVOKING_VERTEX_EXT:
4161 case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
4162 case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
4163 case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
4164 case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
4165 case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
4166 case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
4167 case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
4168 case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
4169 case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
4170 case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
4171 case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
4172 case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
4173 case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
4174 *type = GL_INT;
4175 *numParams = 1;
4176 return true;
4177 }
4178 }
4179
4180 if (extensions.tessellationShaderAny())
4181 {
4182 switch (pname)
4183 {
4184 case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
4185 *type = GL_BOOL;
4186 *numParams = 1;
4187 return true;
4188 case GL_PATCH_VERTICES:
4189 case GL_MAX_PATCH_VERTICES_EXT:
4190 case GL_MAX_TESS_GEN_LEVEL_EXT:
4191 case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
4192 case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
4193 case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
4194 case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
4195 case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
4196 case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
4197 case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
4198 case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
4199 case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
4200 case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
4201 case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
4202 case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
4203 case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
4204 case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
4205 case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
4206 case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
4207 case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
4208 case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
4209 case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
4210 case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
4211 case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
4212 case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
4213 *type = GL_INT;
4214 *numParams = 1;
4215 return true;
4216 }
4217 }
4218
4219 return false;
4220 }
4221
QueryProgramPipelineiv(const Context * context,ProgramPipeline * programPipeline,GLenum pname,GLint * params)4222 void QueryProgramPipelineiv(const Context *context,
4223 ProgramPipeline *programPipeline,
4224 GLenum pname,
4225 GLint *params)
4226 {
4227 if (!params)
4228 {
4229 // Can't write the result anywhere, so just return immediately.
4230 return;
4231 }
4232
4233 switch (pname)
4234 {
4235 case GL_ACTIVE_PROGRAM:
4236 {
4237 // the name of the active program object of the program pipeline object is returned in
4238 // params
4239 *params = 0;
4240 if (programPipeline)
4241 {
4242 const Program *program = programPipeline->getActiveShaderProgram();
4243 if (program)
4244 {
4245 *params = program->id().value;
4246 }
4247 }
4248 break;
4249 }
4250
4251 case GL_VERTEX_SHADER:
4252 {
4253 // the name of the current program object for the vertex shader type of the program
4254 // pipeline object is returned in params
4255 GetShaderProgramId(programPipeline, ShaderType::Vertex, params);
4256 break;
4257 }
4258
4259 case GL_FRAGMENT_SHADER:
4260 {
4261 // the name of the current program object for the fragment shader type of the program
4262 // pipeline object is returned in params
4263 GetShaderProgramId(programPipeline, ShaderType::Fragment, params);
4264 break;
4265 }
4266
4267 case GL_TESS_CONTROL_SHADER:
4268 {
4269 // the name of the current program object for the tessellation control shader type of
4270 // the program pipeline object is returned in params
4271 GetShaderProgramId(programPipeline, ShaderType::TessControl, params);
4272 break;
4273 }
4274
4275 case GL_TESS_EVALUATION_SHADER:
4276 {
4277 // the name of the current program object for the tessellation evaluation shader type of
4278 // the program pipeline object is returned in params
4279 GetShaderProgramId(programPipeline, ShaderType::TessEvaluation, params);
4280 break;
4281 }
4282
4283 case GL_COMPUTE_SHADER:
4284 {
4285 // the name of the current program object for the compute shader type of the program
4286 // pipeline object is returned in params
4287 GetShaderProgramId(programPipeline, ShaderType::Compute, params);
4288 break;
4289 }
4290
4291 case GL_GEOMETRY_SHADER:
4292 {
4293 // the name of the current program object for the geometry shader type of the program
4294 // pipeline object is returned in params
4295 GetShaderProgramId(programPipeline, ShaderType::Geometry, params);
4296 break;
4297 }
4298
4299 case GL_INFO_LOG_LENGTH:
4300 {
4301 // the length of the info log, including the null terminator, is returned in params. If
4302 // there is no info log, zero is returned.
4303 *params = 0;
4304 if (programPipeline)
4305 {
4306 *params = programPipeline->getInfoLogLength();
4307 }
4308 break;
4309 }
4310
4311 case GL_VALIDATE_STATUS:
4312 {
4313 // the validation status of pipeline, as determined by glValidateProgramPipeline, is
4314 // returned in params
4315 *params = 0;
4316 if (programPipeline)
4317 {
4318 *params = programPipeline->isValid();
4319 }
4320 break;
4321 }
4322
4323 default:
4324 break;
4325 }
4326 }
4327
4328 } // namespace gl
4329
4330 namespace egl
4331 {
4332
QueryConfigAttrib(const Config * config,EGLint attribute,EGLint * value)4333 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
4334 {
4335 ASSERT(config != nullptr);
4336 switch (attribute)
4337 {
4338 case EGL_BUFFER_SIZE:
4339 *value = config->bufferSize;
4340 break;
4341 case EGL_ALPHA_SIZE:
4342 *value = config->alphaSize;
4343 break;
4344 case EGL_BLUE_SIZE:
4345 *value = config->blueSize;
4346 break;
4347 case EGL_GREEN_SIZE:
4348 *value = config->greenSize;
4349 break;
4350 case EGL_RED_SIZE:
4351 *value = config->redSize;
4352 break;
4353 case EGL_DEPTH_SIZE:
4354 *value = config->depthSize;
4355 break;
4356 case EGL_STENCIL_SIZE:
4357 *value = config->stencilSize;
4358 break;
4359 case EGL_CONFIG_CAVEAT:
4360 *value = config->configCaveat;
4361 break;
4362 case EGL_CONFIG_ID:
4363 *value = config->configID;
4364 break;
4365 case EGL_LEVEL:
4366 *value = config->level;
4367 break;
4368 case EGL_NATIVE_RENDERABLE:
4369 *value = config->nativeRenderable;
4370 break;
4371 case EGL_NATIVE_VISUAL_ID:
4372 *value = config->nativeVisualID;
4373 break;
4374 case EGL_NATIVE_VISUAL_TYPE:
4375 *value = config->nativeVisualType;
4376 break;
4377 case EGL_SAMPLES:
4378 *value = config->samples;
4379 break;
4380 case EGL_SAMPLE_BUFFERS:
4381 *value = config->sampleBuffers;
4382 break;
4383 case EGL_SURFACE_TYPE:
4384 *value = config->surfaceType;
4385 break;
4386 case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
4387 *value = config->bindToTextureTarget;
4388 break;
4389 case EGL_TRANSPARENT_TYPE:
4390 *value = config->transparentType;
4391 break;
4392 case EGL_TRANSPARENT_BLUE_VALUE:
4393 *value = config->transparentBlueValue;
4394 break;
4395 case EGL_TRANSPARENT_GREEN_VALUE:
4396 *value = config->transparentGreenValue;
4397 break;
4398 case EGL_TRANSPARENT_RED_VALUE:
4399 *value = config->transparentRedValue;
4400 break;
4401 case EGL_BIND_TO_TEXTURE_RGB:
4402 *value = config->bindToTextureRGB;
4403 break;
4404 case EGL_BIND_TO_TEXTURE_RGBA:
4405 *value = config->bindToTextureRGBA;
4406 break;
4407 case EGL_MIN_SWAP_INTERVAL:
4408 *value = config->minSwapInterval;
4409 break;
4410 case EGL_MAX_SWAP_INTERVAL:
4411 *value = config->maxSwapInterval;
4412 break;
4413 case EGL_LUMINANCE_SIZE:
4414 *value = config->luminanceSize;
4415 break;
4416 case EGL_ALPHA_MASK_SIZE:
4417 *value = config->alphaMaskSize;
4418 break;
4419 case EGL_COLOR_BUFFER_TYPE:
4420 *value = config->colorBufferType;
4421 break;
4422 case EGL_RENDERABLE_TYPE:
4423 *value = config->renderableType;
4424 break;
4425 case EGL_MATCH_NATIVE_PIXMAP:
4426 *value = false;
4427 UNIMPLEMENTED();
4428 break;
4429 case EGL_CONFORMANT:
4430 *value = config->conformant;
4431 break;
4432 case EGL_MAX_PBUFFER_WIDTH:
4433 *value = config->maxPBufferWidth;
4434 break;
4435 case EGL_MAX_PBUFFER_HEIGHT:
4436 *value = config->maxPBufferHeight;
4437 break;
4438 case EGL_MAX_PBUFFER_PIXELS:
4439 *value = config->maxPBufferPixels;
4440 break;
4441 case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
4442 *value = config->optimalOrientation;
4443 break;
4444 case EGL_COLOR_COMPONENT_TYPE_EXT:
4445 *value = config->colorComponentType;
4446 break;
4447 case EGL_RECORDABLE_ANDROID:
4448 *value = config->recordable;
4449 break;
4450 case EGL_FRAMEBUFFER_TARGET_ANDROID:
4451 *value = config->framebufferTarget;
4452 break;
4453 case EGL_MATCH_FORMAT_KHR:
4454 *value = config->matchFormat;
4455 break;
4456 default:
4457 UNREACHABLE();
4458 break;
4459 }
4460 }
4461
QueryContextAttrib(const gl::Context * context,EGLint attribute,EGLint * value)4462 void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
4463 {
4464 switch (attribute)
4465 {
4466 case EGL_CONFIG_ID:
4467 if (context->getConfig() != EGL_NO_CONFIG_KHR)
4468 {
4469 *value = context->getConfig()->configID;
4470 }
4471 else
4472 {
4473 *value = 0;
4474 }
4475 break;
4476 case EGL_CONTEXT_CLIENT_TYPE:
4477 *value = context->getClientType();
4478 break;
4479 case EGL_CONTEXT_CLIENT_VERSION:
4480 *value = context->getClientMajorVersion();
4481 break;
4482 case EGL_RENDER_BUFFER:
4483 *value = context->getRenderBuffer();
4484 break;
4485 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4486 *value = context->isRobustResourceInitEnabled();
4487 break;
4488 case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
4489 *value = static_cast<EGLint>(context->getContextPriority());
4490 break;
4491 case EGL_PROTECTED_CONTENT_EXT:
4492 *value = context->getState().hasProtectedContent();
4493 break;
4494 default:
4495 UNREACHABLE();
4496 break;
4497 }
4498 }
4499
QuerySurfaceAttrib(const Display * display,const gl::Context * context,Surface * surface,EGLint attribute,EGLint * value)4500 egl::Error QuerySurfaceAttrib(const Display *display,
4501 const gl::Context *context,
4502 Surface *surface,
4503 EGLint attribute,
4504 EGLint *value)
4505 {
4506 switch (attribute)
4507 {
4508 case EGL_GL_COLORSPACE:
4509 *value = surface->getGLColorspace();
4510 break;
4511 case EGL_VG_ALPHA_FORMAT:
4512 *value = surface->getVGAlphaFormat();
4513 break;
4514 case EGL_VG_COLORSPACE:
4515 *value = surface->getVGColorspace();
4516 break;
4517 case EGL_CONFIG_ID:
4518 *value = surface->getConfig()->configID;
4519 break;
4520 case EGL_HEIGHT:
4521 ANGLE_TRY(surface->getUserHeight(display, value));
4522 break;
4523 case EGL_HORIZONTAL_RESOLUTION:
4524 *value = surface->getHorizontalResolution();
4525 break;
4526 case EGL_LARGEST_PBUFFER:
4527 // The EGL spec states that value is not written if the surface is not a pbuffer
4528 if (surface->getType() == EGL_PBUFFER_BIT)
4529 {
4530 *value = surface->getLargestPbuffer();
4531 }
4532 break;
4533 case EGL_MIPMAP_TEXTURE:
4534 // The EGL spec states that value is not written if the surface is not a pbuffer
4535 if (surface->getType() == EGL_PBUFFER_BIT)
4536 {
4537 *value = surface->getMipmapTexture();
4538 }
4539 break;
4540 case EGL_MIPMAP_LEVEL:
4541 // The EGL spec states that value is not written if the surface is not a pbuffer
4542 if (surface->getType() == EGL_PBUFFER_BIT)
4543 {
4544 *value = surface->getMipmapLevel();
4545 }
4546 break;
4547 case EGL_MULTISAMPLE_RESOLVE:
4548 *value = surface->getMultisampleResolve();
4549 break;
4550 case EGL_PIXEL_ASPECT_RATIO:
4551 *value = surface->getPixelAspectRatio();
4552 break;
4553 case EGL_RENDER_BUFFER:
4554 *value = surface->getRenderBuffer();
4555 break;
4556 case EGL_SWAP_BEHAVIOR:
4557 *value = surface->getSwapBehavior();
4558 break;
4559 case EGL_TEXTURE_FORMAT:
4560 // The EGL spec states that value is not written if the surface is not a pbuffer
4561 if (surface->getType() == EGL_PBUFFER_BIT)
4562 {
4563 *value = ToEGLenum(surface->getTextureFormat());
4564 }
4565 break;
4566 case EGL_TEXTURE_TARGET:
4567 // The EGL spec states that value is not written if the surface is not a pbuffer
4568 if (surface->getType() == EGL_PBUFFER_BIT)
4569 {
4570 *value = surface->getTextureTarget();
4571 }
4572 break;
4573 case EGL_VERTICAL_RESOLUTION:
4574 *value = surface->getVerticalResolution();
4575 break;
4576 case EGL_WIDTH:
4577 ANGLE_TRY(surface->getUserWidth(display, value));
4578 break;
4579 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
4580 *value = surface->isPostSubBufferSupported();
4581 break;
4582 case EGL_FIXED_SIZE_ANGLE:
4583 *value = surface->isFixedSize();
4584 break;
4585 case EGL_SURFACE_ORIENTATION_ANGLE:
4586 *value = surface->getOrientation();
4587 break;
4588 case EGL_DIRECT_COMPOSITION_ANGLE:
4589 *value = surface->directComposition();
4590 break;
4591 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4592 *value = surface->isRobustResourceInitEnabled();
4593 break;
4594 case EGL_TIMESTAMPS_ANDROID:
4595 *value = surface->isTimestampsEnabled();
4596 break;
4597 case EGL_BUFFER_AGE_EXT:
4598 ANGLE_TRY(surface->getBufferAge(context, value));
4599 break;
4600 case EGL_BITMAP_PITCH_KHR:
4601 *value = surface->getBitmapPitch();
4602 break;
4603 case EGL_BITMAP_ORIGIN_KHR:
4604 *value = surface->getBitmapOrigin();
4605 break;
4606 case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
4607 *value = surface->getRedOffset();
4608 break;
4609 case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
4610 *value = surface->getGreenOffset();
4611 break;
4612 case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
4613 *value = surface->getBlueOffset();
4614 break;
4615 case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
4616 *value = surface->getAlphaOffset();
4617 break;
4618 case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
4619 *value = surface->getLuminanceOffset();
4620 break;
4621 case EGL_BITMAP_PIXEL_SIZE_KHR:
4622 *value = surface->getBitmapPixelSize();
4623 break;
4624 case EGL_PROTECTED_CONTENT_EXT:
4625 *value = surface->hasProtectedContent();
4626 break;
4627 default:
4628 UNREACHABLE();
4629 break;
4630 }
4631 return NoError();
4632 }
4633
QuerySurfaceAttrib64KHR(const Display * display,const gl::Context * context,Surface * surface,EGLint attribute,EGLAttribKHR * value)4634 egl::Error QuerySurfaceAttrib64KHR(const Display *display,
4635 const gl::Context *context,
4636 Surface *surface,
4637 EGLint attribute,
4638 EGLAttribKHR *value)
4639 {
4640 switch (attribute)
4641 {
4642 case EGL_BITMAP_PITCH_KHR:
4643 *value = static_cast<EGLAttribKHR>(surface->getBitmapPitch());
4644 break;
4645 case EGL_BITMAP_ORIGIN_KHR:
4646 *value = static_cast<EGLAttribKHR>(surface->getBitmapOrigin());
4647 break;
4648 case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
4649 *value = static_cast<EGLAttribKHR>(surface->getRedOffset());
4650 break;
4651 case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
4652 *value = static_cast<EGLAttribKHR>(surface->getGreenOffset());
4653 break;
4654 case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
4655 *value = static_cast<EGLAttribKHR>(surface->getBlueOffset());
4656 break;
4657 case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
4658 *value = static_cast<EGLAttribKHR>(surface->getAlphaOffset());
4659 break;
4660 case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
4661 *value = static_cast<EGLAttribKHR>(surface->getLuminanceOffset());
4662 break;
4663 case EGL_BITMAP_PIXEL_SIZE_KHR:
4664 *value = static_cast<EGLAttribKHR>(surface->getBitmapPixelSize());
4665 break;
4666 case EGL_BITMAP_POINTER_KHR:
4667 *value = surface->getBitmapPointer();
4668 break;
4669 default:
4670 {
4671 EGLint intValue = 0;
4672 ANGLE_TRY(QuerySurfaceAttrib(display, context, surface, attribute, &intValue));
4673 *value = static_cast<EGLAttribKHR>(intValue);
4674 }
4675 break;
4676 }
4677 return NoError();
4678 }
4679
SetSurfaceAttrib(Surface * surface,EGLint attribute,EGLint value)4680 egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
4681 {
4682 switch (attribute)
4683 {
4684 case EGL_MIPMAP_LEVEL:
4685 surface->setMipmapLevel(value);
4686 break;
4687 case EGL_MULTISAMPLE_RESOLVE:
4688 surface->setMultisampleResolve(value);
4689 break;
4690 case EGL_SWAP_BEHAVIOR:
4691 surface->setSwapBehavior(value);
4692 break;
4693 case EGL_WIDTH:
4694 surface->setFixedWidth(value);
4695 break;
4696 case EGL_HEIGHT:
4697 surface->setFixedHeight(value);
4698 break;
4699 case EGL_TIMESTAMPS_ANDROID:
4700 surface->setTimestampsEnabled(value != EGL_FALSE);
4701 break;
4702 case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID:
4703 return surface->setAutoRefreshEnabled(value == EGL_TRUE);
4704 case EGL_RENDER_BUFFER:
4705 return surface->setRenderBuffer(value);
4706 default:
4707 UNREACHABLE();
4708 break;
4709 }
4710 return NoError();
4711 }
4712
GetSyncAttrib(Display * display,SyncID sync,EGLint attribute,EGLint * value)4713 Error GetSyncAttrib(Display *display, SyncID sync, EGLint attribute, EGLint *value)
4714 {
4715 const egl::Sync *syncObj = display->getSync(sync);
4716 switch (attribute)
4717 {
4718 case EGL_SYNC_TYPE_KHR:
4719 *value = syncObj->getType();
4720 return NoError();
4721
4722 case EGL_SYNC_STATUS_KHR:
4723 return syncObj->getStatus(display, value);
4724
4725 case EGL_SYNC_CONDITION_KHR:
4726 *value = syncObj->getCondition();
4727 return NoError();
4728
4729 default:
4730 break;
4731 }
4732
4733 UNREACHABLE();
4734 return NoError();
4735 }
4736 } // namespace egl
4737