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 "common/utilities.h"
12
13 #include "libANGLE/Buffer.h"
14 #include "libANGLE/Config.h"
15 #include "libANGLE/Context.h"
16 #include "libANGLE/Display.h"
17 #include "libANGLE/EGLSync.h"
18 #include "libANGLE/Fence.h"
19 #include "libANGLE/Framebuffer.h"
20 #include "libANGLE/GLES1State.h"
21 #include "libANGLE/Program.h"
22 #include "libANGLE/Renderbuffer.h"
23 #include "libANGLE/Sampler.h"
24 #include "libANGLE/Shader.h"
25 #include "libANGLE/Surface.h"
26 #include "libANGLE/Texture.h"
27 #include "libANGLE/Uniform.h"
28 #include "libANGLE/VertexAttribute.h"
29 #include "libANGLE/queryconversions.h"
30
31 namespace gl
32 {
33
34 namespace
35 {
36
37 template <bool isPureInteger>
ConvertToColor(const GLfloat * params)38 ColorGeneric ConvertToColor(const GLfloat *params)
39 {
40 if (isPureInteger)
41 {
42 UNREACHABLE();
43 return ColorGeneric(ColorI());
44 }
45 else
46 {
47 return ColorGeneric(ColorF::fromData(params));
48 }
49 }
50
51 template <bool isPureInteger>
ConvertToColor(const GLint * params)52 ColorGeneric ConvertToColor(const GLint *params)
53 {
54 if (isPureInteger)
55 {
56 return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
57 }
58 else
59 {
60 return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
61 normalizedToFloat(params[2]), normalizedToFloat(params[3])));
62 }
63 }
64
65 template <bool isPureInteger>
ConvertToColor(const GLuint * params)66 ColorGeneric ConvertToColor(const GLuint *params)
67 {
68 if (isPureInteger)
69 {
70 return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
71 }
72 else
73 {
74 UNREACHABLE();
75 return ColorGeneric(ColorF());
76 }
77 }
78
79 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLfloat * outParams)80 void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
81 {
82 if (isPureInteger)
83 {
84 UNREACHABLE();
85 }
86 else
87 {
88 ASSERT(color.type == ColorGeneric::Type::Float);
89 color.colorF.writeData(outParams);
90 }
91 }
92
93 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLint * outParams)94 void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
95 {
96 if (isPureInteger)
97 {
98 ASSERT(color.type == ColorGeneric::Type::Int);
99 outParams[0] = color.colorI.red;
100 outParams[1] = color.colorI.green;
101 outParams[2] = color.colorI.blue;
102 outParams[3] = color.colorI.alpha;
103 }
104 else
105 {
106 ASSERT(color.type == ColorGeneric::Type::Float);
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 ASSERT(color.type == ColorGeneric::Type::UInt);
120 outParams[0] = color.colorUI.red;
121 outParams[1] = color.colorUI.green;
122 outParams[2] = color.colorUI.blue;
123 outParams[3] = color.colorUI.alpha;
124 }
125 else
126 {
127 UNREACHABLE();
128 }
129 }
130
131 template <typename ParamType>
QueryTexLevelParameterBase(const Texture * texture,TextureTarget target,GLint level,GLenum pname,ParamType * params)132 void QueryTexLevelParameterBase(const Texture *texture,
133 TextureTarget target,
134 GLint level,
135 GLenum pname,
136 ParamType *params)
137 {
138 ASSERT(texture != nullptr);
139 const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
140
141 switch (pname)
142 {
143 case GL_TEXTURE_RED_TYPE:
144 *params = CastFromGLintStateValue<ParamType>(
145 pname, info->redBits ? info->componentType : GL_NONE);
146 break;
147 case GL_TEXTURE_GREEN_TYPE:
148 *params = CastFromGLintStateValue<ParamType>(
149 pname, info->greenBits ? info->componentType : GL_NONE);
150 break;
151 case GL_TEXTURE_BLUE_TYPE:
152 *params = CastFromGLintStateValue<ParamType>(
153 pname, info->blueBits ? info->componentType : GL_NONE);
154 break;
155 case GL_TEXTURE_ALPHA_TYPE:
156 *params = CastFromGLintStateValue<ParamType>(
157 pname, info->alphaBits ? info->componentType : GL_NONE);
158 break;
159 case GL_TEXTURE_DEPTH_TYPE:
160 *params = CastFromGLintStateValue<ParamType>(
161 pname, info->depthBits ? info->componentType : GL_NONE);
162 break;
163 case GL_TEXTURE_RED_SIZE:
164 *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
165 break;
166 case GL_TEXTURE_GREEN_SIZE:
167 *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
168 break;
169 case GL_TEXTURE_BLUE_SIZE:
170 *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
171 break;
172 case GL_TEXTURE_ALPHA_SIZE:
173 *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
174 break;
175 case GL_TEXTURE_DEPTH_SIZE:
176 *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
177 break;
178 case GL_TEXTURE_STENCIL_SIZE:
179 *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
180 break;
181 case GL_TEXTURE_SHARED_SIZE:
182 *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
183 break;
184 case GL_TEXTURE_INTERNAL_FORMAT:
185 *params = CastFromGLintStateValue<ParamType>(
186 pname, info->internalFormat ? info->internalFormat : GL_RGBA);
187 break;
188 case GL_TEXTURE_WIDTH:
189 *params = CastFromGLintStateValue<ParamType>(
190 pname, static_cast<uint32_t>(texture->getWidth(target, level)));
191 break;
192 case GL_TEXTURE_HEIGHT:
193 *params = CastFromGLintStateValue<ParamType>(
194 pname, static_cast<uint32_t>(texture->getHeight(target, level)));
195 break;
196 case GL_TEXTURE_DEPTH:
197 *params = CastFromGLintStateValue<ParamType>(
198 pname, static_cast<uint32_t>(texture->getDepth(target, level)));
199 break;
200 case GL_TEXTURE_SAMPLES:
201 *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
202 break;
203 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
204 *params = CastFromStateValue<ParamType>(
205 pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
206 break;
207 case GL_TEXTURE_COMPRESSED:
208 *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
209 break;
210 case GL_MEMORY_SIZE_ANGLE:
211 *params =
212 CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
213 break;
214 default:
215 UNREACHABLE();
216 break;
217 }
218 }
219
220 template <bool isPureInteger, typename ParamType>
QueryTexParameterBase(const Texture * texture,GLenum pname,ParamType * params)221 void QueryTexParameterBase(const Texture *texture, GLenum pname, ParamType *params)
222 {
223 ASSERT(texture != nullptr);
224
225 switch (pname)
226 {
227 case GL_TEXTURE_MAG_FILTER:
228 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
229 break;
230 case GL_TEXTURE_MIN_FILTER:
231 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
232 break;
233 case GL_TEXTURE_WRAP_S:
234 *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
235 break;
236 case GL_TEXTURE_WRAP_T:
237 *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
238 break;
239 case GL_TEXTURE_WRAP_R:
240 *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
241 break;
242 case GL_TEXTURE_IMMUTABLE_FORMAT:
243 *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
244 break;
245 case GL_TEXTURE_IMMUTABLE_LEVELS:
246 *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
247 break;
248 case GL_TEXTURE_USAGE_ANGLE:
249 *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
250 break;
251 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
252 *params = CastFromStateValue<ParamType>(pname, texture->getMaxAnisotropy());
253 break;
254 case GL_TEXTURE_SWIZZLE_R:
255 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
256 break;
257 case GL_TEXTURE_SWIZZLE_G:
258 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
259 break;
260 case GL_TEXTURE_SWIZZLE_B:
261 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
262 break;
263 case GL_TEXTURE_SWIZZLE_A:
264 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
265 break;
266 case GL_TEXTURE_BASE_LEVEL:
267 *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
268 break;
269 case GL_TEXTURE_MAX_LEVEL:
270 *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
271 break;
272 case GL_TEXTURE_MIN_LOD:
273 *params = CastFromStateValue<ParamType>(pname, texture->getMinLod());
274 break;
275 case GL_TEXTURE_MAX_LOD:
276 *params = CastFromStateValue<ParamType>(pname, texture->getMaxLod());
277 break;
278 case GL_TEXTURE_COMPARE_MODE:
279 *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
280 break;
281 case GL_TEXTURE_COMPARE_FUNC:
282 *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
283 break;
284 case GL_TEXTURE_SRGB_DECODE_EXT:
285 *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
286 break;
287 case GL_DEPTH_STENCIL_TEXTURE_MODE:
288 *params =
289 CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
290 break;
291 case GL_TEXTURE_CROP_RECT_OES:
292 {
293 const gl::Rectangle &crop = texture->getCrop();
294 params[0] = CastFromGLintStateValue<ParamType>(pname, crop.x);
295 params[1] = CastFromGLintStateValue<ParamType>(pname, crop.y);
296 params[2] = CastFromGLintStateValue<ParamType>(pname, crop.width);
297 params[3] = CastFromGLintStateValue<ParamType>(pname, crop.height);
298 break;
299 }
300 case GL_GENERATE_MIPMAP:
301 *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
302 break;
303 case GL_MEMORY_SIZE_ANGLE:
304 *params = CastFromStateValue<ParamType>(pname, texture->getMemorySize());
305 break;
306 case GL_TEXTURE_BORDER_COLOR:
307 ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
308 break;
309 case GL_TEXTURE_NATIVE_ID_ANGLE:
310 *params = CastFromStateValue<ParamType>(pname, texture->getNativeID());
311 break;
312 default:
313 UNREACHABLE();
314 break;
315 }
316 }
317
318 template <bool isPureInteger, typename ParamType>
SetTexParameterBase(Context * context,Texture * texture,GLenum pname,const ParamType * params)319 void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
320 {
321 ASSERT(texture != nullptr);
322
323 switch (pname)
324 {
325 case GL_TEXTURE_WRAP_S:
326 texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
327 break;
328 case GL_TEXTURE_WRAP_T:
329 texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
330 break;
331 case GL_TEXTURE_WRAP_R:
332 texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
333 break;
334 case GL_TEXTURE_MIN_FILTER:
335 texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
336 break;
337 case GL_TEXTURE_MAG_FILTER:
338 texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
339 break;
340 case GL_TEXTURE_USAGE_ANGLE:
341 texture->setUsage(context, ConvertToGLenum(pname, params[0]));
342 break;
343 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
344 texture->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
345 break;
346 case GL_TEXTURE_COMPARE_MODE:
347 texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
348 break;
349 case GL_TEXTURE_COMPARE_FUNC:
350 texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
351 break;
352 case GL_TEXTURE_SWIZZLE_R:
353 texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
354 break;
355 case GL_TEXTURE_SWIZZLE_G:
356 texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
357 break;
358 case GL_TEXTURE_SWIZZLE_B:
359 texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
360 break;
361 case GL_TEXTURE_SWIZZLE_A:
362 texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
363 break;
364 case GL_TEXTURE_BASE_LEVEL:
365 {
366 (void)(texture->setBaseLevel(
367 context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
368 break;
369 }
370 case GL_TEXTURE_MAX_LEVEL:
371 texture->setMaxLevel(context,
372 clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
373 break;
374 case GL_TEXTURE_MIN_LOD:
375 texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
376 break;
377 case GL_TEXTURE_MAX_LOD:
378 texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
379 break;
380 case GL_DEPTH_STENCIL_TEXTURE_MODE:
381 texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
382 break;
383 case GL_TEXTURE_SRGB_DECODE_EXT:
384 texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
385 break;
386 case GL_TEXTURE_CROP_RECT_OES:
387 texture->setCrop(gl::Rectangle(CastQueryValueTo<GLint>(pname, params[0]),
388 CastQueryValueTo<GLint>(pname, params[1]),
389 CastQueryValueTo<GLint>(pname, params[2]),
390 CastQueryValueTo<GLint>(pname, params[3])));
391 break;
392 case GL_GENERATE_MIPMAP:
393 texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
394 break;
395 case GL_TEXTURE_BORDER_COLOR:
396 texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
397 break;
398 default:
399 UNREACHABLE();
400 break;
401 }
402 }
403
404 template <bool isPureInteger, typename ParamType>
QuerySamplerParameterBase(const Sampler * sampler,GLenum pname,ParamType * params)405 void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
406 {
407 switch (pname)
408 {
409 case GL_TEXTURE_MIN_FILTER:
410 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
411 break;
412 case GL_TEXTURE_MAG_FILTER:
413 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
414 break;
415 case GL_TEXTURE_WRAP_S:
416 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
417 break;
418 case GL_TEXTURE_WRAP_T:
419 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
420 break;
421 case GL_TEXTURE_WRAP_R:
422 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
423 break;
424 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
425 *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
426 break;
427 case GL_TEXTURE_MIN_LOD:
428 *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
429 break;
430 case GL_TEXTURE_MAX_LOD:
431 *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
432 break;
433 case GL_TEXTURE_COMPARE_MODE:
434 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
435 break;
436 case GL_TEXTURE_COMPARE_FUNC:
437 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
438 break;
439 case GL_TEXTURE_SRGB_DECODE_EXT:
440 *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
441 break;
442 case GL_TEXTURE_BORDER_COLOR:
443 ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
444 break;
445 default:
446 UNREACHABLE();
447 break;
448 }
449 }
450
451 template <bool isPureInteger, typename ParamType>
SetSamplerParameterBase(Context * context,Sampler * sampler,GLenum pname,const ParamType * params)452 void SetSamplerParameterBase(Context *context,
453 Sampler *sampler,
454 GLenum pname,
455 const ParamType *params)
456 {
457 switch (pname)
458 {
459 case GL_TEXTURE_WRAP_S:
460 sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
461 break;
462 case GL_TEXTURE_WRAP_T:
463 sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
464 break;
465 case GL_TEXTURE_WRAP_R:
466 sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
467 break;
468 case GL_TEXTURE_MIN_FILTER:
469 sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
470 break;
471 case GL_TEXTURE_MAG_FILTER:
472 sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
473 break;
474 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
475 sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
476 break;
477 case GL_TEXTURE_COMPARE_MODE:
478 sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
479 break;
480 case GL_TEXTURE_COMPARE_FUNC:
481 sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
482 break;
483 case GL_TEXTURE_MIN_LOD:
484 sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
485 break;
486 case GL_TEXTURE_MAX_LOD:
487 sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
488 break;
489 case GL_TEXTURE_SRGB_DECODE_EXT:
490 sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
491 break;
492 case GL_TEXTURE_BORDER_COLOR:
493 sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
494 break;
495 default:
496 UNREACHABLE();
497 break;
498 }
499
500 sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
501 }
502
503 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
504 template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
QueryVertexAttribBase(const VertexAttribute & attrib,const VertexBinding & binding,const CurrentDataType (& currentValueData)[CurrentValueCount],GLenum pname,ParamType * params)505 void QueryVertexAttribBase(const VertexAttribute &attrib,
506 const VertexBinding &binding,
507 const CurrentDataType (¤tValueData)[CurrentValueCount],
508 GLenum pname,
509 ParamType *params)
510 {
511 switch (pname)
512 {
513 case GL_CURRENT_VERTEX_ATTRIB:
514 for (size_t i = 0; i < CurrentValueCount; ++i)
515 {
516 params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
517 }
518 break;
519 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
520 *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
521 break;
522 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
523 *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
524 break;
525 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
526 *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
527 break;
528 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
529 *params = CastFromGLintStateValue<ParamType>(
530 pname, gl::ToGLenum(attrib.format->vertexAttribType));
531 break;
532 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
533 *params =
534 CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
535 break;
536 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
537 *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id());
538 break;
539 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
540 *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
541 break;
542 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
543 *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
544 break;
545 case GL_VERTEX_ATTRIB_BINDING:
546 *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
547 break;
548 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
549 *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
550 break;
551 default:
552 UNREACHABLE();
553 break;
554 }
555 }
556
557 template <typename ParamType>
QueryBufferParameterBase(const Buffer * buffer,GLenum pname,ParamType * params)558 void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
559 {
560 ASSERT(buffer != nullptr);
561
562 switch (pname)
563 {
564 case GL_BUFFER_USAGE:
565 *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
566 break;
567 case GL_BUFFER_SIZE:
568 *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
569 break;
570 case GL_BUFFER_ACCESS_FLAGS:
571 *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
572 break;
573 case GL_BUFFER_ACCESS_OES:
574 *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
575 break;
576 case GL_BUFFER_MAPPED:
577 *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
578 break;
579 case GL_BUFFER_MAP_OFFSET:
580 *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
581 break;
582 case GL_BUFFER_MAP_LENGTH:
583 *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
584 break;
585 case GL_MEMORY_SIZE_ANGLE:
586 *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
587 break;
588 default:
589 UNREACHABLE();
590 break;
591 }
592 }
593
GetCommonVariableProperty(const sh::ShaderVariable & var,GLenum prop)594 GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
595 {
596 switch (prop)
597 {
598 case GL_TYPE:
599 return clampCast<GLint>(var.type);
600
601 case GL_ARRAY_SIZE:
602 // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
603 // see GLES 3.1 spec section 7.3.1.1 page 77.
604 return clampCast<GLint>(var.getBasicTypeElementCount());
605
606 case GL_NAME_LENGTH:
607 // ES31 spec p84: This counts the terminating null char.
608 return clampCast<GLint>(var.name.size() + 1u);
609
610 default:
611 UNREACHABLE();
612 return GL_INVALID_VALUE;
613 }
614 }
615
GetInputResourceProperty(const Program * program,GLuint index,GLenum prop)616 GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
617 {
618 const auto &attribute = program->getInputResource(index);
619 switch (prop)
620 {
621 case GL_TYPE:
622 case GL_ARRAY_SIZE:
623 case GL_NAME_LENGTH:
624 return GetCommonVariableProperty(attribute, prop);
625
626 case GL_LOCATION:
627 return program->getAttributeLocation(attribute.name);
628
629 case GL_REFERENCED_BY_VERTEX_SHADER:
630 return 1;
631
632 case GL_REFERENCED_BY_FRAGMENT_SHADER:
633 case GL_REFERENCED_BY_COMPUTE_SHADER:
634 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
635 return 0;
636
637 default:
638 UNREACHABLE();
639 return GL_INVALID_VALUE;
640 }
641 }
642
GetOutputResourceProperty(const Program * program,GLuint index,const GLenum prop)643 GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
644 {
645 const auto &outputVariable = program->getOutputResource(index);
646 switch (prop)
647 {
648 case GL_TYPE:
649 case GL_ARRAY_SIZE:
650 case GL_NAME_LENGTH:
651 return GetCommonVariableProperty(outputVariable, prop);
652
653 case GL_LOCATION:
654 return program->getFragDataLocation(outputVariable.name);
655
656 case GL_LOCATION_INDEX_EXT:
657 // EXT_blend_func_extended
658 return program->getFragDataIndex(outputVariable.name);
659
660 case GL_REFERENCED_BY_FRAGMENT_SHADER:
661 return 1;
662
663 case GL_REFERENCED_BY_VERTEX_SHADER:
664 case GL_REFERENCED_BY_COMPUTE_SHADER:
665 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
666 return 0;
667
668 default:
669 UNREACHABLE();
670 return GL_INVALID_VALUE;
671 }
672 }
673
GetTransformFeedbackVaryingResourceProperty(const Program * program,GLuint index,const GLenum prop)674 GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
675 GLuint index,
676 const GLenum prop)
677 {
678 const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
679 switch (prop)
680 {
681 case GL_TYPE:
682 return clampCast<GLint>(tfVariable.type);
683
684 case GL_ARRAY_SIZE:
685 return clampCast<GLint>(tfVariable.size());
686
687 case GL_NAME_LENGTH:
688 return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
689
690 default:
691 UNREACHABLE();
692 return GL_INVALID_VALUE;
693 }
694 }
695
QueryProgramInterfaceActiveResources(const Program * program,GLenum programInterface)696 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
697 {
698 switch (programInterface)
699 {
700 case GL_PROGRAM_INPUT:
701 return clampCast<GLint>(program->getAttributes().size());
702
703 case GL_PROGRAM_OUTPUT:
704 return clampCast<GLint>(program->getState().getOutputVariables().size());
705
706 case GL_UNIFORM:
707 return clampCast<GLint>(program->getState().getUniforms().size());
708
709 case GL_UNIFORM_BLOCK:
710 return clampCast<GLint>(program->getState().getUniformBlocks().size());
711
712 case GL_ATOMIC_COUNTER_BUFFER:
713 return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
714
715 case GL_BUFFER_VARIABLE:
716 return clampCast<GLint>(program->getState().getBufferVariables().size());
717
718 case GL_SHADER_STORAGE_BLOCK:
719 return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
720
721 case GL_TRANSFORM_FEEDBACK_VARYING:
722 return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
723
724 default:
725 UNREACHABLE();
726 return 0;
727 }
728 }
729
730 template <typename T, typename M>
FindMaxSize(const std::vector<T> & resources,M member)731 GLint FindMaxSize(const std::vector<T> &resources, M member)
732 {
733 GLint max = 0;
734 for (const T &resource : resources)
735 {
736 max = std::max(max, clampCast<GLint>((resource.*member).size()));
737 }
738 return max;
739 }
740
QueryProgramInterfaceMaxNameLength(const Program * program,GLenum programInterface)741 GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
742 {
743 GLint maxNameLength = 0;
744 switch (programInterface)
745 {
746 case GL_PROGRAM_INPUT:
747 maxNameLength = FindMaxSize(program->getAttributes(), &sh::Attribute::name);
748 break;
749
750 case GL_PROGRAM_OUTPUT:
751 maxNameLength =
752 FindMaxSize(program->getState().getOutputVariables(), &sh::OutputVariable::name);
753 break;
754
755 case GL_UNIFORM:
756 maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
757 break;
758
759 case GL_UNIFORM_BLOCK:
760 return program->getActiveUniformBlockMaxNameLength();
761
762 case GL_BUFFER_VARIABLE:
763 maxNameLength =
764 FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
765 break;
766
767 case GL_SHADER_STORAGE_BLOCK:
768 return program->getActiveShaderStorageBlockMaxNameLength();
769
770 case GL_TRANSFORM_FEEDBACK_VARYING:
771 return clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength());
772
773 default:
774 UNREACHABLE();
775 return 0;
776 }
777 // This length includes an extra character for the null terminator.
778 return (maxNameLength == 0 ? 0 : maxNameLength + 1);
779 }
780
QueryProgramInterfaceMaxNumActiveVariables(const Program * program,GLenum programInterface)781 GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
782 {
783 switch (programInterface)
784 {
785 case GL_UNIFORM_BLOCK:
786 return FindMaxSize(program->getState().getUniformBlocks(),
787 &InterfaceBlock::memberIndexes);
788 case GL_ATOMIC_COUNTER_BUFFER:
789 return FindMaxSize(program->getState().getAtomicCounterBuffers(),
790 &AtomicCounterBuffer::memberIndexes);
791
792 case GL_SHADER_STORAGE_BLOCK:
793 return FindMaxSize(program->getState().getShaderStorageBlocks(),
794 &InterfaceBlock::memberIndexes);
795
796 default:
797 UNREACHABLE();
798 return 0;
799 }
800 }
801
GetUniformPropertyEnum(GLenum prop)802 GLenum GetUniformPropertyEnum(GLenum prop)
803 {
804 switch (prop)
805 {
806 case GL_UNIFORM_TYPE:
807 return GL_TYPE;
808 case GL_UNIFORM_SIZE:
809 return GL_ARRAY_SIZE;
810 case GL_UNIFORM_NAME_LENGTH:
811 return GL_NAME_LENGTH;
812 case GL_UNIFORM_BLOCK_INDEX:
813 return GL_BLOCK_INDEX;
814 case GL_UNIFORM_OFFSET:
815 return GL_OFFSET;
816 case GL_UNIFORM_ARRAY_STRIDE:
817 return GL_ARRAY_STRIDE;
818 case GL_UNIFORM_MATRIX_STRIDE:
819 return GL_MATRIX_STRIDE;
820 case GL_UNIFORM_IS_ROW_MAJOR:
821 return GL_IS_ROW_MAJOR;
822
823 default:
824 return prop;
825 }
826 }
827
GetUniformBlockPropertyEnum(GLenum prop)828 GLenum GetUniformBlockPropertyEnum(GLenum prop)
829 {
830 switch (prop)
831 {
832 case GL_UNIFORM_BLOCK_BINDING:
833 return GL_BUFFER_BINDING;
834
835 case GL_UNIFORM_BLOCK_DATA_SIZE:
836 return GL_BUFFER_DATA_SIZE;
837
838 case GL_UNIFORM_BLOCK_NAME_LENGTH:
839 return GL_NAME_LENGTH;
840
841 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
842 return GL_NUM_ACTIVE_VARIABLES;
843
844 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
845 return GL_ACTIVE_VARIABLES;
846
847 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
848 return GL_REFERENCED_BY_VERTEX_SHADER;
849
850 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
851 return GL_REFERENCED_BY_FRAGMENT_SHADER;
852
853 default:
854 return prop;
855 }
856 }
857
GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer & buffer,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)858 void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
859 GLenum pname,
860 GLint *params,
861 GLsizei bufSize,
862 GLsizei *outputPosition)
863
864 {
865 switch (pname)
866 {
867 case GL_BUFFER_BINDING:
868 params[(*outputPosition)++] = buffer.binding;
869 break;
870 case GL_BUFFER_DATA_SIZE:
871 params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
872 break;
873 case GL_NUM_ACTIVE_VARIABLES:
874 params[(*outputPosition)++] = buffer.numActiveVariables();
875 break;
876 case GL_ACTIVE_VARIABLES:
877 for (size_t memberIndex = 0;
878 memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
879 ++memberIndex)
880 {
881 params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
882 }
883 break;
884 case GL_REFERENCED_BY_VERTEX_SHADER:
885 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
886 break;
887 case GL_REFERENCED_BY_FRAGMENT_SHADER:
888 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
889 break;
890 case GL_REFERENCED_BY_COMPUTE_SHADER:
891 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
892 break;
893 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
894 params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
895 break;
896 default:
897 UNREACHABLE();
898 break;
899 }
900 }
901
GetInterfaceBlockResourceProperty(const InterfaceBlock & block,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)902 void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
903 GLenum pname,
904 GLint *params,
905 GLsizei bufSize,
906 GLsizei *outputPosition)
907 {
908 if (pname == GL_NAME_LENGTH)
909 {
910 params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
911 return;
912 }
913 GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
914 }
915
GetUniformBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)916 void GetUniformBlockResourceProperty(const Program *program,
917 GLuint blockIndex,
918 GLenum pname,
919 GLint *params,
920 GLsizei bufSize,
921 GLsizei *outputPosition)
922
923 {
924 ASSERT(*outputPosition < bufSize);
925 const auto &block = program->getUniformBlockByIndex(blockIndex);
926 GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
927 }
928
GetShaderStorageBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)929 void GetShaderStorageBlockResourceProperty(const Program *program,
930 GLuint blockIndex,
931 GLenum pname,
932 GLint *params,
933 GLsizei bufSize,
934 GLsizei *outputPosition)
935
936 {
937 ASSERT(*outputPosition < bufSize);
938 const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
939 GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
940 }
941
GetAtomicCounterBufferResourceProperty(const Program * program,GLuint index,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)942 void GetAtomicCounterBufferResourceProperty(const Program *program,
943 GLuint index,
944 GLenum pname,
945 GLint *params,
946 GLsizei bufSize,
947 GLsizei *outputPosition)
948
949 {
950 ASSERT(*outputPosition < bufSize);
951 const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
952 GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
953 }
954
IsTextureEnvEnumParameter(TextureEnvParameter pname)955 bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
956 {
957 switch (pname)
958 {
959 case TextureEnvParameter::Mode:
960 case TextureEnvParameter::CombineRgb:
961 case TextureEnvParameter::CombineAlpha:
962 case TextureEnvParameter::Src0Rgb:
963 case TextureEnvParameter::Src1Rgb:
964 case TextureEnvParameter::Src2Rgb:
965 case TextureEnvParameter::Src0Alpha:
966 case TextureEnvParameter::Src1Alpha:
967 case TextureEnvParameter::Src2Alpha:
968 case TextureEnvParameter::Op0Rgb:
969 case TextureEnvParameter::Op1Rgb:
970 case TextureEnvParameter::Op2Rgb:
971 case TextureEnvParameter::Op0Alpha:
972 case TextureEnvParameter::Op1Alpha:
973 case TextureEnvParameter::Op2Alpha:
974 case TextureEnvParameter::PointCoordReplace:
975 return true;
976 default:
977 return false;
978 }
979 }
980
981 } // anonymous namespace
982
QueryFramebufferAttachmentParameteriv(const Context * context,const Framebuffer * framebuffer,GLenum attachment,GLenum pname,GLint * params)983 void QueryFramebufferAttachmentParameteriv(const Context *context,
984 const Framebuffer *framebuffer,
985 GLenum attachment,
986 GLenum pname,
987 GLint *params)
988 {
989 ASSERT(framebuffer);
990
991 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
992
993 if (attachmentObject == nullptr)
994 {
995 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
996 // is NONE, then querying any other pname will generate INVALID_ENUM.
997
998 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
999 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
1000 // INVALID_OPERATION for all other pnames
1001
1002 switch (pname)
1003 {
1004 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1005 *params = GL_NONE;
1006 break;
1007
1008 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1009 *params = 0;
1010 break;
1011
1012 default:
1013 UNREACHABLE();
1014 break;
1015 }
1016
1017 return;
1018 }
1019
1020 switch (pname)
1021 {
1022 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1023 *params = attachmentObject->type();
1024 break;
1025
1026 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1027 *params = attachmentObject->id();
1028 break;
1029
1030 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1031 *params = attachmentObject->mipLevel();
1032 break;
1033
1034 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1035 {
1036 TextureTarget face = attachmentObject->cubeMapFace();
1037 if (face != TextureTarget::InvalidEnum)
1038 {
1039 *params = ToGLenum(attachmentObject->cubeMapFace());
1040 }
1041 else
1042 {
1043 // This happens when the attachment isn't a texture cube map face
1044 *params = GL_NONE;
1045 }
1046 }
1047 break;
1048
1049 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
1050 *params = attachmentObject->getRedSize();
1051 break;
1052
1053 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
1054 *params = attachmentObject->getGreenSize();
1055 break;
1056
1057 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
1058 *params = attachmentObject->getBlueSize();
1059 break;
1060
1061 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
1062 *params = attachmentObject->getAlphaSize();
1063 break;
1064
1065 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
1066 *params = attachmentObject->getDepthSize();
1067 break;
1068
1069 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
1070 *params = attachmentObject->getStencilSize();
1071 break;
1072
1073 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
1074 *params = attachmentObject->getComponentType();
1075 break;
1076
1077 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
1078 *params = attachmentObject->getColorEncoding();
1079 break;
1080
1081 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
1082 *params = attachmentObject->layer();
1083 break;
1084
1085 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
1086 *params = attachmentObject->getNumViews();
1087 break;
1088
1089 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
1090 *params = attachmentObject->getBaseViewIndex();
1091 break;
1092
1093 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
1094 *params = attachmentObject->isLayered();
1095 break;
1096
1097 default:
1098 UNREACHABLE();
1099 break;
1100 }
1101 }
1102
QueryBufferParameteriv(const Buffer * buffer,GLenum pname,GLint * params)1103 void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
1104 {
1105 QueryBufferParameterBase(buffer, pname, params);
1106 }
1107
QueryBufferParameteri64v(const Buffer * buffer,GLenum pname,GLint64 * params)1108 void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
1109 {
1110 QueryBufferParameterBase(buffer, pname, params);
1111 }
1112
QueryBufferPointerv(const Buffer * buffer,GLenum pname,void ** params)1113 void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
1114 {
1115 switch (pname)
1116 {
1117 case GL_BUFFER_MAP_POINTER:
1118 *params = buffer->getMapPointer();
1119 break;
1120
1121 default:
1122 UNREACHABLE();
1123 break;
1124 }
1125 }
1126
QueryProgramiv(Context * context,const Program * program,GLenum pname,GLint * params)1127 void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params)
1128 {
1129 ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1130
1131 switch (pname)
1132 {
1133 case GL_DELETE_STATUS:
1134 *params = program->isFlaggedForDeletion();
1135 return;
1136 case GL_LINK_STATUS:
1137 *params = program->isLinked();
1138 return;
1139 case GL_COMPLETION_STATUS_KHR:
1140 if (context->isContextLost())
1141 {
1142 *params = GL_TRUE;
1143 }
1144 else
1145 {
1146 *params = program->isLinking() ? GL_FALSE : GL_TRUE;
1147 }
1148 return;
1149 case GL_VALIDATE_STATUS:
1150 *params = program->isValidated();
1151 return;
1152 case GL_INFO_LOG_LENGTH:
1153 *params = program->getInfoLogLength();
1154 return;
1155 case GL_ATTACHED_SHADERS:
1156 *params = program->getAttachedShadersCount();
1157 return;
1158 case GL_ACTIVE_ATTRIBUTES:
1159 *params = program->getActiveAttributeCount();
1160 return;
1161 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1162 *params = program->getActiveAttributeMaxLength();
1163 return;
1164 case GL_ACTIVE_UNIFORMS:
1165 *params = program->getActiveUniformCount();
1166 return;
1167 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1168 *params = program->getActiveUniformMaxLength();
1169 return;
1170 case GL_PROGRAM_BINARY_LENGTH_OES:
1171 *params = context->getCaps().programBinaryFormats.empty()
1172 ? 0
1173 : program->getBinaryLength(context);
1174 return;
1175 case GL_ACTIVE_UNIFORM_BLOCKS:
1176 *params = program->getActiveUniformBlockCount();
1177 return;
1178 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
1179 *params = program->getActiveUniformBlockMaxNameLength();
1180 break;
1181 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
1182 *params = program->getTransformFeedbackBufferMode();
1183 break;
1184 case GL_TRANSFORM_FEEDBACK_VARYINGS:
1185 *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
1186 break;
1187 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
1188 *params = program->getTransformFeedbackVaryingMaxLength();
1189 break;
1190 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1191 *params = program->getBinaryRetrievableHint();
1192 break;
1193 case GL_PROGRAM_SEPARABLE:
1194 *params = program->isSeparable();
1195 break;
1196 case GL_COMPUTE_WORK_GROUP_SIZE:
1197 {
1198 const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
1199 params[0] = localSize[0];
1200 params[1] = localSize[1];
1201 params[2] = localSize[2];
1202 }
1203 break;
1204 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
1205 *params = program->getActiveAtomicCounterBufferCount();
1206 break;
1207 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
1208 *params = ToGLenum(program->getGeometryShaderInputPrimitiveType());
1209 break;
1210 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
1211 *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType());
1212 break;
1213 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
1214 *params = program->getGeometryShaderMaxVertices();
1215 break;
1216 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
1217 *params = program->getGeometryShaderInvocations();
1218 break;
1219 default:
1220 UNREACHABLE();
1221 break;
1222 }
1223 }
1224
QueryRenderbufferiv(const Context * context,const Renderbuffer * renderbuffer,GLenum pname,GLint * params)1225 void QueryRenderbufferiv(const Context *context,
1226 const Renderbuffer *renderbuffer,
1227 GLenum pname,
1228 GLint *params)
1229 {
1230 ASSERT(renderbuffer != nullptr);
1231
1232 switch (pname)
1233 {
1234 case GL_RENDERBUFFER_WIDTH:
1235 *params = renderbuffer->getWidth();
1236 break;
1237 case GL_RENDERBUFFER_HEIGHT:
1238 *params = renderbuffer->getHeight();
1239 break;
1240 case GL_RENDERBUFFER_INTERNAL_FORMAT:
1241 // Special case the WebGL 1 DEPTH_STENCIL format.
1242 if (context->isWebGL1() &&
1243 renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
1244 {
1245 *params = GL_DEPTH_STENCIL;
1246 }
1247 else
1248 {
1249 *params = renderbuffer->getFormat().info->internalFormat;
1250 }
1251 break;
1252 case GL_RENDERBUFFER_RED_SIZE:
1253 *params = renderbuffer->getRedSize();
1254 break;
1255 case GL_RENDERBUFFER_GREEN_SIZE:
1256 *params = renderbuffer->getGreenSize();
1257 break;
1258 case GL_RENDERBUFFER_BLUE_SIZE:
1259 *params = renderbuffer->getBlueSize();
1260 break;
1261 case GL_RENDERBUFFER_ALPHA_SIZE:
1262 *params = renderbuffer->getAlphaSize();
1263 break;
1264 case GL_RENDERBUFFER_DEPTH_SIZE:
1265 *params = renderbuffer->getDepthSize();
1266 break;
1267 case GL_RENDERBUFFER_STENCIL_SIZE:
1268 *params = renderbuffer->getStencilSize();
1269 break;
1270 case GL_RENDERBUFFER_SAMPLES_ANGLE:
1271 *params = renderbuffer->getSamples();
1272 break;
1273 case GL_MEMORY_SIZE_ANGLE:
1274 *params = renderbuffer->getMemorySize();
1275 break;
1276 default:
1277 UNREACHABLE();
1278 break;
1279 }
1280 }
1281
QueryShaderiv(const Context * context,Shader * shader,GLenum pname,GLint * params)1282 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
1283 {
1284 ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1285
1286 switch (pname)
1287 {
1288 case GL_SHADER_TYPE:
1289 *params = static_cast<GLint>(ToGLenum(shader->getType()));
1290 return;
1291 case GL_DELETE_STATUS:
1292 *params = shader->isFlaggedForDeletion();
1293 return;
1294 case GL_COMPILE_STATUS:
1295 *params = shader->isCompiled() ? GL_TRUE : GL_FALSE;
1296 return;
1297 case GL_COMPLETION_STATUS_KHR:
1298 if (context->isContextLost())
1299 {
1300 *params = GL_TRUE;
1301 }
1302 else
1303 {
1304 *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
1305 }
1306 return;
1307 case GL_INFO_LOG_LENGTH:
1308 *params = shader->getInfoLogLength();
1309 return;
1310 case GL_SHADER_SOURCE_LENGTH:
1311 *params = shader->getSourceLength();
1312 return;
1313 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
1314 *params = shader->getTranslatedSourceWithDebugInfoLength();
1315 return;
1316 default:
1317 UNREACHABLE();
1318 break;
1319 }
1320 }
1321
QueryTexLevelParameterfv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLfloat * params)1322 void QueryTexLevelParameterfv(const Texture *texture,
1323 TextureTarget target,
1324 GLint level,
1325 GLenum pname,
1326 GLfloat *params)
1327 {
1328 QueryTexLevelParameterBase(texture, target, level, pname, params);
1329 }
1330
QueryTexLevelParameteriv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLint * params)1331 void QueryTexLevelParameteriv(const Texture *texture,
1332 TextureTarget target,
1333 GLint level,
1334 GLenum pname,
1335 GLint *params)
1336 {
1337 QueryTexLevelParameterBase(texture, target, level, pname, params);
1338 }
1339
QueryTexParameterfv(const Texture * texture,GLenum pname,GLfloat * params)1340 void QueryTexParameterfv(const Texture *texture, GLenum pname, GLfloat *params)
1341 {
1342 QueryTexParameterBase<false>(texture, pname, params);
1343 }
1344
QueryTexParameteriv(const Texture * texture,GLenum pname,GLint * params)1345 void QueryTexParameteriv(const Texture *texture, GLenum pname, GLint *params)
1346 {
1347 QueryTexParameterBase<false>(texture, pname, params);
1348 }
1349
QueryTexParameterIiv(const Texture * texture,GLenum pname,GLint * params)1350 void QueryTexParameterIiv(const Texture *texture, GLenum pname, GLint *params)
1351 {
1352 QueryTexParameterBase<true>(texture, pname, params);
1353 }
1354
QueryTexParameterIuiv(const Texture * texture,GLenum pname,GLuint * params)1355 void QueryTexParameterIuiv(const Texture *texture, GLenum pname, GLuint *params)
1356 {
1357 QueryTexParameterBase<true>(texture, pname, params);
1358 }
1359
QuerySamplerParameterfv(const Sampler * sampler,GLenum pname,GLfloat * params)1360 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
1361 {
1362 QuerySamplerParameterBase<false>(sampler, pname, params);
1363 }
1364
QuerySamplerParameteriv(const Sampler * sampler,GLenum pname,GLint * params)1365 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
1366 {
1367 QuerySamplerParameterBase<false>(sampler, pname, params);
1368 }
1369
QuerySamplerParameterIiv(const Sampler * sampler,GLenum pname,GLint * params)1370 void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
1371 {
1372 QuerySamplerParameterBase<true>(sampler, pname, params);
1373 }
1374
QuerySamplerParameterIuiv(const Sampler * sampler,GLenum pname,GLuint * params)1375 void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
1376 {
1377 QuerySamplerParameterBase<true>(sampler, pname, params);
1378 }
1379
QueryVertexAttribfv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLfloat * params)1380 void QueryVertexAttribfv(const VertexAttribute &attrib,
1381 const VertexBinding &binding,
1382 const VertexAttribCurrentValueData ¤tValueData,
1383 GLenum pname,
1384 GLfloat *params)
1385 {
1386 QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1387 }
1388
QueryVertexAttribiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1389 void QueryVertexAttribiv(const VertexAttribute &attrib,
1390 const VertexBinding &binding,
1391 const VertexAttribCurrentValueData ¤tValueData,
1392 GLenum pname,
1393 GLint *params)
1394 {
1395 QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1396 }
1397
QueryVertexAttribPointerv(const VertexAttribute & attrib,GLenum pname,void ** pointer)1398 void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
1399 {
1400 switch (pname)
1401 {
1402 case GL_VERTEX_ATTRIB_ARRAY_POINTER:
1403 *pointer = const_cast<void *>(attrib.pointer);
1404 break;
1405
1406 default:
1407 UNREACHABLE();
1408 break;
1409 }
1410 }
1411
QueryVertexAttribIiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1412 void QueryVertexAttribIiv(const VertexAttribute &attrib,
1413 const VertexBinding &binding,
1414 const VertexAttribCurrentValueData ¤tValueData,
1415 GLenum pname,
1416 GLint *params)
1417 {
1418 QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
1419 }
1420
QueryVertexAttribIuiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLuint * params)1421 void QueryVertexAttribIuiv(const VertexAttribute &attrib,
1422 const VertexBinding &binding,
1423 const VertexAttribCurrentValueData ¤tValueData,
1424 GLenum pname,
1425 GLuint *params)
1426 {
1427 QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
1428 params);
1429 }
1430
QueryActiveUniformBlockiv(const Program * program,GLuint uniformBlockIndex,GLenum pname,GLint * params)1431 void QueryActiveUniformBlockiv(const Program *program,
1432 GLuint uniformBlockIndex,
1433 GLenum pname,
1434 GLint *params)
1435 {
1436 GLenum prop = GetUniformBlockPropertyEnum(pname);
1437 QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
1438 std::numeric_limits<GLsizei>::max(), nullptr, params);
1439 }
1440
QueryInternalFormativ(const TextureCaps & format,GLenum pname,GLsizei bufSize,GLint * params)1441 void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
1442 {
1443 switch (pname)
1444 {
1445 case GL_NUM_SAMPLE_COUNTS:
1446 if (bufSize != 0)
1447 {
1448 *params = clampCast<GLint>(format.sampleCounts.size());
1449 }
1450 break;
1451
1452 case GL_SAMPLES:
1453 {
1454 size_t returnCount = std::min<size_t>(bufSize, format.sampleCounts.size());
1455 auto sampleReverseIt = format.sampleCounts.rbegin();
1456 for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
1457 {
1458 params[sampleIndex] = *sampleReverseIt++;
1459 }
1460 }
1461 break;
1462
1463 default:
1464 UNREACHABLE();
1465 break;
1466 }
1467 }
1468
QueryFramebufferParameteriv(const Framebuffer * framebuffer,GLenum pname,GLint * params)1469 void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
1470 {
1471 ASSERT(framebuffer);
1472
1473 switch (pname)
1474 {
1475 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1476 *params = framebuffer->getDefaultWidth();
1477 break;
1478 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1479 *params = framebuffer->getDefaultHeight();
1480 break;
1481 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1482 *params = framebuffer->getDefaultSamples();
1483 break;
1484 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1485 *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
1486 break;
1487 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1488 *params = framebuffer->getDefaultLayers();
1489 break;
1490 default:
1491 UNREACHABLE();
1492 break;
1493 }
1494 }
1495
QuerySynciv(const Context * context,const Sync * sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)1496 angle::Result QuerySynciv(const Context *context,
1497 const Sync *sync,
1498 GLenum pname,
1499 GLsizei bufSize,
1500 GLsizei *length,
1501 GLint *values)
1502 {
1503 ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
1504
1505 // All queries return one value, exit early if the buffer can't fit anything.
1506 if (bufSize < 1)
1507 {
1508 if (length != nullptr)
1509 {
1510 *length = 0;
1511 }
1512 return angle::Result::Continue;
1513 }
1514
1515 switch (pname)
1516 {
1517 case GL_OBJECT_TYPE:
1518 *values = clampCast<GLint>(GL_SYNC_FENCE);
1519 break;
1520 case GL_SYNC_CONDITION:
1521 *values = clampCast<GLint>(sync->getCondition());
1522 break;
1523 case GL_SYNC_FLAGS:
1524 *values = clampCast<GLint>(sync->getFlags());
1525 break;
1526 case GL_SYNC_STATUS:
1527 if (context->isContextLost())
1528 {
1529 *values = GL_SIGNALED;
1530 }
1531 else
1532 {
1533 ANGLE_TRY(sync->getStatus(context, values));
1534 }
1535 break;
1536
1537 default:
1538 UNREACHABLE();
1539 break;
1540 }
1541
1542 if (length != nullptr)
1543 {
1544 *length = 1;
1545 }
1546
1547 return angle::Result::Continue;
1548 }
1549
SetTexParameterf(Context * context,Texture * texture,GLenum pname,GLfloat param)1550 void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
1551 {
1552 SetTexParameterBase<false>(context, texture, pname, ¶m);
1553 }
1554
SetTexParameterfv(Context * context,Texture * texture,GLenum pname,const GLfloat * params)1555 void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
1556 {
1557 SetTexParameterBase<false>(context, texture, pname, params);
1558 }
1559
SetTexParameteri(Context * context,Texture * texture,GLenum pname,GLint param)1560 void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
1561 {
1562 SetTexParameterBase<false>(context, texture, pname, ¶m);
1563 }
1564
SetTexParameteriv(Context * context,Texture * texture,GLenum pname,const GLint * params)1565 void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1566 {
1567 SetTexParameterBase<false>(context, texture, pname, params);
1568 }
1569
SetTexParameterIiv(Context * context,Texture * texture,GLenum pname,const GLint * params)1570 void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1571 {
1572 SetTexParameterBase<true>(context, texture, pname, params);
1573 }
1574
SetTexParameterIuiv(Context * context,Texture * texture,GLenum pname,const GLuint * params)1575 void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
1576 {
1577 SetTexParameterBase<true>(context, texture, pname, params);
1578 }
1579
SetSamplerParameterf(Context * context,Sampler * sampler,GLenum pname,GLfloat param)1580 void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
1581 {
1582 SetSamplerParameterBase<false>(context, sampler, pname, ¶m);
1583 }
1584
SetSamplerParameterfv(Context * context,Sampler * sampler,GLenum pname,const GLfloat * params)1585 void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
1586 {
1587 SetSamplerParameterBase<false>(context, sampler, pname, params);
1588 }
1589
SetSamplerParameteri(Context * context,Sampler * sampler,GLenum pname,GLint param)1590 void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
1591 {
1592 SetSamplerParameterBase<false>(context, sampler, pname, ¶m);
1593 }
1594
SetSamplerParameteriv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1595 void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1596 {
1597 SetSamplerParameterBase<false>(context, sampler, pname, params);
1598 }
1599
SetSamplerParameterIiv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1600 void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1601 {
1602 SetSamplerParameterBase<true>(context, sampler, pname, params);
1603 }
1604
SetSamplerParameterIuiv(Context * context,Sampler * sampler,GLenum pname,const GLuint * params)1605 void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
1606 {
1607 SetSamplerParameterBase<true>(context, sampler, pname, params);
1608 }
1609
SetFramebufferParameteri(const Context * context,Framebuffer * framebuffer,GLenum pname,GLint param)1610 void SetFramebufferParameteri(const Context *context,
1611 Framebuffer *framebuffer,
1612 GLenum pname,
1613 GLint param)
1614 {
1615 ASSERT(framebuffer);
1616
1617 switch (pname)
1618 {
1619 case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1620 framebuffer->setDefaultWidth(context, param);
1621 break;
1622 case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1623 framebuffer->setDefaultHeight(context, param);
1624 break;
1625 case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1626 framebuffer->setDefaultSamples(context, param);
1627 break;
1628 case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1629 framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
1630 break;
1631 case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1632 framebuffer->setDefaultLayers(param);
1633 break;
1634 default:
1635 UNREACHABLE();
1636 break;
1637 }
1638 }
1639
SetProgramParameteri(Program * program,GLenum pname,GLint value)1640 void SetProgramParameteri(Program *program, GLenum pname, GLint value)
1641 {
1642 ASSERT(program);
1643
1644 switch (pname)
1645 {
1646 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1647 program->setBinaryRetrievableHint(ConvertToBool(value));
1648 break;
1649 case GL_PROGRAM_SEPARABLE:
1650 program->setSeparable(ConvertToBool(value));
1651 break;
1652 default:
1653 UNREACHABLE();
1654 break;
1655 }
1656 }
1657
GetUniformResourceProperty(const Program * program,GLuint index,const GLenum prop)1658 GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
1659 {
1660 const auto &uniform = program->getUniformByIndex(index);
1661 GLenum resourceProp = GetUniformPropertyEnum(prop);
1662 switch (resourceProp)
1663 {
1664 case GL_TYPE:
1665 case GL_ARRAY_SIZE:
1666 case GL_NAME_LENGTH:
1667 return GetCommonVariableProperty(uniform, resourceProp);
1668
1669 case GL_LOCATION:
1670 return program->getUniformLocation(uniform.name);
1671
1672 case GL_BLOCK_INDEX:
1673 return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
1674
1675 case GL_OFFSET:
1676 return uniform.blockInfo.offset;
1677
1678 case GL_ARRAY_STRIDE:
1679 return uniform.blockInfo.arrayStride;
1680
1681 case GL_MATRIX_STRIDE:
1682 return uniform.blockInfo.matrixStride;
1683
1684 case GL_IS_ROW_MAJOR:
1685 return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
1686
1687 case GL_REFERENCED_BY_VERTEX_SHADER:
1688 return uniform.isActive(ShaderType::Vertex);
1689
1690 case GL_REFERENCED_BY_FRAGMENT_SHADER:
1691 return uniform.isActive(ShaderType::Fragment);
1692
1693 case GL_REFERENCED_BY_COMPUTE_SHADER:
1694 return uniform.isActive(ShaderType::Compute);
1695
1696 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1697 return uniform.isActive(ShaderType::Geometry);
1698
1699 case GL_ATOMIC_COUNTER_BUFFER_INDEX:
1700 return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
1701
1702 default:
1703 UNREACHABLE();
1704 return 0;
1705 }
1706 }
1707
GetBufferVariableResourceProperty(const Program * program,GLuint index,const GLenum prop)1708 GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
1709 {
1710 const auto &bufferVariable = program->getBufferVariableByIndex(index);
1711 switch (prop)
1712 {
1713 case GL_TYPE:
1714 case GL_ARRAY_SIZE:
1715 case GL_NAME_LENGTH:
1716 return GetCommonVariableProperty(bufferVariable, prop);
1717
1718 case GL_BLOCK_INDEX:
1719 return bufferVariable.bufferIndex;
1720
1721 case GL_OFFSET:
1722 return bufferVariable.blockInfo.offset;
1723
1724 case GL_ARRAY_STRIDE:
1725 return bufferVariable.blockInfo.arrayStride;
1726
1727 case GL_MATRIX_STRIDE:
1728 return bufferVariable.blockInfo.matrixStride;
1729
1730 case GL_IS_ROW_MAJOR:
1731 return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
1732
1733 case GL_REFERENCED_BY_VERTEX_SHADER:
1734 return bufferVariable.isActive(ShaderType::Vertex);
1735
1736 case GL_REFERENCED_BY_FRAGMENT_SHADER:
1737 return bufferVariable.isActive(ShaderType::Fragment);
1738
1739 case GL_REFERENCED_BY_COMPUTE_SHADER:
1740 return bufferVariable.isActive(ShaderType::Compute);
1741
1742 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1743 return bufferVariable.isActive(ShaderType::Geometry);
1744
1745 case GL_TOP_LEVEL_ARRAY_SIZE:
1746 return bufferVariable.topLevelArraySize;
1747
1748 case GL_TOP_LEVEL_ARRAY_STRIDE:
1749 return bufferVariable.blockInfo.topLevelArrayStride;
1750
1751 default:
1752 UNREACHABLE();
1753 return 0;
1754 }
1755 }
1756
QueryProgramResourceIndex(const Program * program,GLenum programInterface,const GLchar * name)1757 GLuint QueryProgramResourceIndex(const Program *program,
1758 GLenum programInterface,
1759 const GLchar *name)
1760 {
1761 switch (programInterface)
1762 {
1763 case GL_PROGRAM_INPUT:
1764 return program->getInputResourceIndex(name);
1765
1766 case GL_PROGRAM_OUTPUT:
1767 return program->getOutputResourceIndex(name);
1768
1769 case GL_UNIFORM:
1770 return program->getState().getUniformIndexFromName(name);
1771
1772 case GL_BUFFER_VARIABLE:
1773 return program->getState().getBufferVariableIndexFromName(name);
1774
1775 case GL_SHADER_STORAGE_BLOCK:
1776 return program->getShaderStorageBlockIndex(name);
1777
1778 case GL_UNIFORM_BLOCK:
1779 return program->getUniformBlockIndex(name);
1780
1781 case GL_TRANSFORM_FEEDBACK_VARYING:
1782 return program->getTransformFeedbackVaryingResourceIndex(name);
1783
1784 default:
1785 UNREACHABLE();
1786 return GL_INVALID_INDEX;
1787 }
1788 }
1789
QueryProgramResourceName(const Program * program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)1790 void QueryProgramResourceName(const Program *program,
1791 GLenum programInterface,
1792 GLuint index,
1793 GLsizei bufSize,
1794 GLsizei *length,
1795 GLchar *name)
1796 {
1797 switch (programInterface)
1798 {
1799 case GL_PROGRAM_INPUT:
1800 program->getInputResourceName(index, bufSize, length, name);
1801 break;
1802
1803 case GL_PROGRAM_OUTPUT:
1804 program->getOutputResourceName(index, bufSize, length, name);
1805 break;
1806
1807 case GL_UNIFORM:
1808 program->getUniformResourceName(index, bufSize, length, name);
1809 break;
1810
1811 case GL_BUFFER_VARIABLE:
1812 program->getBufferVariableResourceName(index, bufSize, length, name);
1813 break;
1814
1815 case GL_SHADER_STORAGE_BLOCK:
1816 program->getActiveShaderStorageBlockName(index, bufSize, length, name);
1817 break;
1818
1819 case GL_UNIFORM_BLOCK:
1820 program->getActiveUniformBlockName(index, bufSize, length, name);
1821 break;
1822
1823 case GL_TRANSFORM_FEEDBACK_VARYING:
1824 program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
1825 break;
1826
1827 default:
1828 UNREACHABLE();
1829 }
1830 }
1831
QueryProgramResourceLocation(const Program * program,GLenum programInterface,const GLchar * name)1832 GLint QueryProgramResourceLocation(const Program *program,
1833 GLenum programInterface,
1834 const GLchar *name)
1835 {
1836 switch (programInterface)
1837 {
1838 case GL_PROGRAM_INPUT:
1839 return program->getAttributeLocation(name);
1840
1841 case GL_PROGRAM_OUTPUT:
1842 return program->getFragDataLocation(name);
1843
1844 case GL_UNIFORM:
1845 return program->getUniformLocation(name);
1846
1847 default:
1848 UNREACHABLE();
1849 return -1;
1850 }
1851 }
1852
QueryProgramResourceiv(const Program * program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)1853 void QueryProgramResourceiv(const Program *program,
1854 GLenum programInterface,
1855 GLuint index,
1856 GLsizei propCount,
1857 const GLenum *props,
1858 GLsizei bufSize,
1859 GLsizei *length,
1860 GLint *params)
1861 {
1862 if (!program->isLinked())
1863 {
1864 if (length != nullptr)
1865 {
1866 *length = 0;
1867 }
1868 return;
1869 }
1870
1871 GLsizei pos = 0;
1872 for (GLsizei i = 0; i < propCount; i++)
1873 {
1874 switch (programInterface)
1875 {
1876 case GL_PROGRAM_INPUT:
1877 params[i] = GetInputResourceProperty(program, index, props[i]);
1878 ++pos;
1879 break;
1880
1881 case GL_PROGRAM_OUTPUT:
1882 params[i] = GetOutputResourceProperty(program, index, props[i]);
1883 ++pos;
1884 break;
1885
1886 case GL_UNIFORM:
1887 params[i] = GetUniformResourceProperty(program, index, props[i]);
1888 ++pos;
1889 break;
1890
1891 case GL_BUFFER_VARIABLE:
1892 params[i] = GetBufferVariableResourceProperty(program, index, props[i]);
1893 ++pos;
1894 break;
1895
1896 case GL_UNIFORM_BLOCK:
1897 GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos);
1898 break;
1899
1900 case GL_SHADER_STORAGE_BLOCK:
1901 GetShaderStorageBlockResourceProperty(program, index, props[i], params, bufSize,
1902 &pos);
1903 break;
1904
1905 case GL_ATOMIC_COUNTER_BUFFER:
1906 GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize,
1907 &pos);
1908 break;
1909
1910 case GL_TRANSFORM_FEEDBACK_VARYING:
1911 params[i] = GetTransformFeedbackVaryingResourceProperty(program, index, props[i]);
1912 ++pos;
1913 break;
1914
1915 default:
1916 UNREACHABLE();
1917 params[i] = GL_INVALID_VALUE;
1918 }
1919 if (pos == bufSize)
1920 {
1921 // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
1922 // This checks not to break buffer bounds for such case.
1923 break;
1924 }
1925 }
1926
1927 if (length != nullptr)
1928 {
1929 *length = pos;
1930 }
1931 }
1932
QueryProgramInterfaceiv(const Program * program,GLenum programInterface,GLenum pname,GLint * params)1933 void QueryProgramInterfaceiv(const Program *program,
1934 GLenum programInterface,
1935 GLenum pname,
1936 GLint *params)
1937 {
1938 switch (pname)
1939 {
1940 case GL_ACTIVE_RESOURCES:
1941 *params = QueryProgramInterfaceActiveResources(program, programInterface);
1942 break;
1943
1944 case GL_MAX_NAME_LENGTH:
1945 *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
1946 break;
1947
1948 case GL_MAX_NUM_ACTIVE_VARIABLES:
1949 *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
1950 break;
1951
1952 default:
1953 UNREACHABLE();
1954 }
1955 }
1956
ParamToVertexArrayType(GLenum param)1957 ClientVertexArrayType ParamToVertexArrayType(GLenum param)
1958 {
1959 switch (param)
1960 {
1961 case GL_VERTEX_ARRAY:
1962 case GL_VERTEX_ARRAY_BUFFER_BINDING:
1963 case GL_VERTEX_ARRAY_STRIDE:
1964 case GL_VERTEX_ARRAY_SIZE:
1965 case GL_VERTEX_ARRAY_TYPE:
1966 case GL_VERTEX_ARRAY_POINTER:
1967 return ClientVertexArrayType::Vertex;
1968 case GL_NORMAL_ARRAY:
1969 case GL_NORMAL_ARRAY_BUFFER_BINDING:
1970 case GL_NORMAL_ARRAY_STRIDE:
1971 case GL_NORMAL_ARRAY_TYPE:
1972 case GL_NORMAL_ARRAY_POINTER:
1973 return ClientVertexArrayType::Normal;
1974 case GL_COLOR_ARRAY:
1975 case GL_COLOR_ARRAY_BUFFER_BINDING:
1976 case GL_COLOR_ARRAY_STRIDE:
1977 case GL_COLOR_ARRAY_SIZE:
1978 case GL_COLOR_ARRAY_TYPE:
1979 case GL_COLOR_ARRAY_POINTER:
1980 return ClientVertexArrayType::Color;
1981 case GL_POINT_SIZE_ARRAY_OES:
1982 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
1983 case GL_POINT_SIZE_ARRAY_STRIDE_OES:
1984 case GL_POINT_SIZE_ARRAY_TYPE_OES:
1985 case GL_POINT_SIZE_ARRAY_POINTER_OES:
1986 return ClientVertexArrayType::PointSize;
1987 case GL_TEXTURE_COORD_ARRAY:
1988 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
1989 case GL_TEXTURE_COORD_ARRAY_STRIDE:
1990 case GL_TEXTURE_COORD_ARRAY_SIZE:
1991 case GL_TEXTURE_COORD_ARRAY_TYPE:
1992 case GL_TEXTURE_COORD_ARRAY_POINTER:
1993 return ClientVertexArrayType::TextureCoord;
1994 default:
1995 UNREACHABLE();
1996 return ClientVertexArrayType::InvalidEnum;
1997 }
1998 }
1999
SetLightModelParameters(GLES1State * state,GLenum pname,const GLfloat * params)2000 void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2001 {
2002 LightModelParameters &lightModel = state->lightModelParameters();
2003
2004 switch (pname)
2005 {
2006 case GL_LIGHT_MODEL_AMBIENT:
2007 lightModel.color = ColorF::fromData(params);
2008 break;
2009 case GL_LIGHT_MODEL_TWO_SIDE:
2010 lightModel.twoSided = *params == 1.0f ? true : false;
2011 break;
2012 default:
2013 break;
2014 }
2015 }
2016
GetLightModelParameters(const GLES1State * state,GLenum pname,GLfloat * params)2017 void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2018 {
2019 const LightModelParameters &lightModel = state->lightModelParameters();
2020
2021 switch (pname)
2022 {
2023 case GL_LIGHT_MODEL_TWO_SIDE:
2024 *params = lightModel.twoSided ? 1.0f : 0.0f;
2025 break;
2026 case GL_LIGHT_MODEL_AMBIENT:
2027 lightModel.color.writeData(params);
2028 break;
2029 default:
2030 break;
2031 }
2032 }
2033
IsLightModelTwoSided(const GLES1State * state)2034 bool IsLightModelTwoSided(const GLES1State *state)
2035 {
2036 return state->lightModelParameters().twoSided;
2037 }
2038
SetLightParameters(GLES1State * state,GLenum light,LightParameter pname,const GLfloat * params)2039 void SetLightParameters(GLES1State *state,
2040 GLenum light,
2041 LightParameter pname,
2042 const GLfloat *params)
2043 {
2044 uint32_t lightIndex = light - GL_LIGHT0;
2045
2046 LightParameters &lightParams = state->lightParameters(lightIndex);
2047
2048 switch (pname)
2049 {
2050 case LightParameter::Ambient:
2051 lightParams.ambient = ColorF::fromData(params);
2052 break;
2053 case LightParameter::Diffuse:
2054 lightParams.diffuse = ColorF::fromData(params);
2055 break;
2056 case LightParameter::Specular:
2057 lightParams.specular = ColorF::fromData(params);
2058 break;
2059 case LightParameter::Position:
2060 {
2061 angle::Mat4 mv = state->getModelviewMatrix();
2062 angle::Vector4 transformedPos =
2063 mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
2064 lightParams.position[0] = transformedPos[0];
2065 lightParams.position[1] = transformedPos[1];
2066 lightParams.position[2] = transformedPos[2];
2067 lightParams.position[3] = transformedPos[3];
2068 }
2069 break;
2070 case LightParameter::SpotDirection:
2071 {
2072 angle::Mat4 mv = state->getModelviewMatrix();
2073 angle::Vector4 transformedPos =
2074 mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
2075 lightParams.direction[0] = transformedPos[0];
2076 lightParams.direction[1] = transformedPos[1];
2077 lightParams.direction[2] = transformedPos[2];
2078 }
2079 break;
2080 case LightParameter::SpotExponent:
2081 lightParams.spotlightExponent = *params;
2082 break;
2083 case LightParameter::SpotCutoff:
2084 lightParams.spotlightCutoffAngle = *params;
2085 break;
2086 case LightParameter::ConstantAttenuation:
2087 lightParams.attenuationConst = *params;
2088 break;
2089 case LightParameter::LinearAttenuation:
2090 lightParams.attenuationLinear = *params;
2091 break;
2092 case LightParameter::QuadraticAttenuation:
2093 lightParams.attenuationQuadratic = *params;
2094 break;
2095 default:
2096 return;
2097 }
2098 }
2099
GetLightParameters(const GLES1State * state,GLenum light,LightParameter pname,GLfloat * params)2100 void GetLightParameters(const GLES1State *state,
2101 GLenum light,
2102 LightParameter pname,
2103 GLfloat *params)
2104 {
2105 uint32_t lightIndex = light - GL_LIGHT0;
2106 const LightParameters &lightParams = state->lightParameters(lightIndex);
2107
2108 switch (pname)
2109 {
2110 case LightParameter::Ambient:
2111 lightParams.ambient.writeData(params);
2112 break;
2113 case LightParameter::Diffuse:
2114 lightParams.diffuse.writeData(params);
2115 break;
2116 case LightParameter::Specular:
2117 lightParams.specular.writeData(params);
2118 break;
2119 case LightParameter::Position:
2120 memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
2121 break;
2122 case LightParameter::SpotDirection:
2123 memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
2124 break;
2125 case LightParameter::SpotExponent:
2126 *params = lightParams.spotlightExponent;
2127 break;
2128 case LightParameter::SpotCutoff:
2129 *params = lightParams.spotlightCutoffAngle;
2130 break;
2131 case LightParameter::ConstantAttenuation:
2132 *params = lightParams.attenuationConst;
2133 break;
2134 case LightParameter::LinearAttenuation:
2135 *params = lightParams.attenuationLinear;
2136 break;
2137 case LightParameter::QuadraticAttenuation:
2138 *params = lightParams.attenuationQuadratic;
2139 break;
2140 default:
2141 break;
2142 }
2143 }
2144
SetMaterialParameters(GLES1State * state,GLenum face,MaterialParameter pname,const GLfloat * params)2145 void SetMaterialParameters(GLES1State *state,
2146 GLenum face,
2147 MaterialParameter pname,
2148 const GLfloat *params)
2149 {
2150 MaterialParameters &material = state->materialParameters();
2151 switch (pname)
2152 {
2153 case MaterialParameter::Ambient:
2154 material.ambient = ColorF::fromData(params);
2155 break;
2156 case MaterialParameter::Diffuse:
2157 material.diffuse = ColorF::fromData(params);
2158 break;
2159 case MaterialParameter::AmbientAndDiffuse:
2160 material.ambient = ColorF::fromData(params);
2161 material.diffuse = ColorF::fromData(params);
2162 break;
2163 case MaterialParameter::Specular:
2164 material.specular = ColorF::fromData(params);
2165 break;
2166 case MaterialParameter::Emission:
2167 material.emissive = ColorF::fromData(params);
2168 break;
2169 case MaterialParameter::Shininess:
2170 material.specularExponent = *params;
2171 break;
2172 default:
2173 return;
2174 }
2175 }
2176
GetMaterialParameters(const GLES1State * state,GLenum face,MaterialParameter pname,GLfloat * params)2177 void GetMaterialParameters(const GLES1State *state,
2178 GLenum face,
2179 MaterialParameter pname,
2180 GLfloat *params)
2181 {
2182 const ColorF ¤tColor = state->getCurrentColor();
2183 const MaterialParameters &material = state->materialParameters();
2184 const bool colorMaterialEnabled = state->isColorMaterialEnabled();
2185
2186 switch (pname)
2187 {
2188 case MaterialParameter::Ambient:
2189 if (colorMaterialEnabled)
2190 {
2191 currentColor.writeData(params);
2192 }
2193 else
2194 {
2195 material.ambient.writeData(params);
2196 }
2197 break;
2198 case MaterialParameter::Diffuse:
2199 if (colorMaterialEnabled)
2200 {
2201 currentColor.writeData(params);
2202 }
2203 else
2204 {
2205 material.diffuse.writeData(params);
2206 }
2207 break;
2208 case MaterialParameter::Specular:
2209 material.specular.writeData(params);
2210 break;
2211 case MaterialParameter::Emission:
2212 material.emissive.writeData(params);
2213 break;
2214 case MaterialParameter::Shininess:
2215 *params = material.specularExponent;
2216 break;
2217 default:
2218 return;
2219 }
2220 }
2221
GetLightModelParameterCount(GLenum pname)2222 unsigned int GetLightModelParameterCount(GLenum pname)
2223 {
2224 switch (pname)
2225 {
2226 case GL_LIGHT_MODEL_AMBIENT:
2227 return 4;
2228 case GL_LIGHT_MODEL_TWO_SIDE:
2229 return 1;
2230 default:
2231 return 0;
2232 }
2233 }
2234
GetLightParameterCount(LightParameter pname)2235 unsigned int GetLightParameterCount(LightParameter pname)
2236 {
2237 switch (pname)
2238 {
2239 case LightParameter::Ambient:
2240 case LightParameter::Diffuse:
2241 case LightParameter::Specular:
2242 case LightParameter::Position:
2243 return 4;
2244 case LightParameter::SpotDirection:
2245 return 3;
2246 case LightParameter::SpotExponent:
2247 case LightParameter::SpotCutoff:
2248 case LightParameter::ConstantAttenuation:
2249 case LightParameter::LinearAttenuation:
2250 case LightParameter::QuadraticAttenuation:
2251 return 1;
2252 default:
2253 return 0;
2254 }
2255 }
2256
GetMaterialParameterCount(MaterialParameter pname)2257 unsigned int GetMaterialParameterCount(MaterialParameter pname)
2258 {
2259 switch (pname)
2260 {
2261 case MaterialParameter::Ambient:
2262 case MaterialParameter::Diffuse:
2263 case MaterialParameter::Specular:
2264 case MaterialParameter::Emission:
2265 return 4;
2266 case MaterialParameter::Shininess:
2267 return 1;
2268 default:
2269 return 0;
2270 }
2271 }
2272
SetFogParameters(GLES1State * state,GLenum pname,const GLfloat * params)2273 void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2274 {
2275 FogParameters &fog = state->fogParameters();
2276 switch (pname)
2277 {
2278 case GL_FOG_MODE:
2279 fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
2280 break;
2281 case GL_FOG_DENSITY:
2282 fog.density = params[0];
2283 break;
2284 case GL_FOG_START:
2285 fog.start = params[0];
2286 break;
2287 case GL_FOG_END:
2288 fog.end = params[0];
2289 break;
2290 case GL_FOG_COLOR:
2291 fog.color = ColorF::fromData(params);
2292 break;
2293 default:
2294 return;
2295 }
2296 }
2297
GetFogParameters(const GLES1State * state,GLenum pname,GLfloat * params)2298 void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2299 {
2300 const FogParameters &fog = state->fogParameters();
2301 switch (pname)
2302 {
2303 case GL_FOG_MODE:
2304 params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
2305 break;
2306 case GL_FOG_DENSITY:
2307 params[0] = fog.density;
2308 break;
2309 case GL_FOG_START:
2310 params[0] = fog.start;
2311 break;
2312 case GL_FOG_END:
2313 params[0] = fog.end;
2314 break;
2315 case GL_FOG_COLOR:
2316 fog.color.writeData(params);
2317 break;
2318 default:
2319 return;
2320 }
2321 }
2322
GetFogParameterCount(GLenum pname)2323 unsigned int GetFogParameterCount(GLenum pname)
2324 {
2325 switch (pname)
2326 {
2327 case GL_FOG_MODE:
2328 case GL_FOG_DENSITY:
2329 case GL_FOG_START:
2330 case GL_FOG_END:
2331 return 1;
2332 case GL_FOG_COLOR:
2333 return 4;
2334 default:
2335 return 0;
2336 }
2337 }
2338
GetTextureEnvParameterCount(TextureEnvParameter pname)2339 unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
2340 {
2341 switch (pname)
2342 {
2343 case TextureEnvParameter::Mode:
2344 case TextureEnvParameter::CombineRgb:
2345 case TextureEnvParameter::CombineAlpha:
2346 case TextureEnvParameter::Src0Rgb:
2347 case TextureEnvParameter::Src1Rgb:
2348 case TextureEnvParameter::Src2Rgb:
2349 case TextureEnvParameter::Src0Alpha:
2350 case TextureEnvParameter::Src1Alpha:
2351 case TextureEnvParameter::Src2Alpha:
2352 case TextureEnvParameter::Op0Rgb:
2353 case TextureEnvParameter::Op1Rgb:
2354 case TextureEnvParameter::Op2Rgb:
2355 case TextureEnvParameter::Op0Alpha:
2356 case TextureEnvParameter::Op1Alpha:
2357 case TextureEnvParameter::Op2Alpha:
2358 case TextureEnvParameter::RgbScale:
2359 case TextureEnvParameter::AlphaScale:
2360 case TextureEnvParameter::PointCoordReplace:
2361 return 1;
2362 case TextureEnvParameter::Color:
2363 return 4;
2364 default:
2365 return 0;
2366 }
2367 }
2368
ConvertTextureEnvFromInt(TextureEnvParameter pname,const GLint * input,GLfloat * output)2369 void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
2370 {
2371 if (IsTextureEnvEnumParameter(pname))
2372 {
2373 ConvertGLenumValue(input[0], output);
2374 return;
2375 }
2376
2377 switch (pname)
2378 {
2379 case TextureEnvParameter::RgbScale:
2380 case TextureEnvParameter::AlphaScale:
2381 output[0] = static_cast<GLfloat>(input[0]);
2382 break;
2383 case TextureEnvParameter::Color:
2384 for (int i = 0; i < 4; i++)
2385 {
2386 output[i] = input[i] / 255.0f;
2387 }
2388 break;
2389 default:
2390 UNREACHABLE();
2391 break;
2392 }
2393 }
2394
ConvertTextureEnvFromFixed(TextureEnvParameter pname,const GLfixed * input,GLfloat * output)2395 void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
2396 {
2397 if (IsTextureEnvEnumParameter(pname))
2398 {
2399 ConvertGLenumValue(input[0], output);
2400 return;
2401 }
2402
2403 switch (pname)
2404 {
2405 case TextureEnvParameter::RgbScale:
2406 case TextureEnvParameter::AlphaScale:
2407 output[0] = FixedToFloat(input[0]);
2408 break;
2409 case TextureEnvParameter::Color:
2410 for (int i = 0; i < 4; i++)
2411 {
2412 output[i] = FixedToFloat(input[i]);
2413 }
2414 break;
2415 default:
2416 UNREACHABLE();
2417 break;
2418 }
2419 }
2420
ConvertTextureEnvToInt(TextureEnvParameter pname,const GLfloat * input,GLint * output)2421 void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
2422 {
2423 if (IsTextureEnvEnumParameter(pname))
2424 {
2425 ConvertGLenumValue(input[0], output);
2426 return;
2427 }
2428
2429 switch (pname)
2430 {
2431 case TextureEnvParameter::RgbScale:
2432 case TextureEnvParameter::AlphaScale:
2433 output[0] = static_cast<GLint>(input[0]);
2434 break;
2435 case TextureEnvParameter::Color:
2436 for (int i = 0; i < 4; i++)
2437 {
2438 output[i] = static_cast<GLint>(input[i] * 255.0f);
2439 }
2440 break;
2441 default:
2442 UNREACHABLE();
2443 break;
2444 }
2445 }
2446
ConvertTextureEnvToFixed(TextureEnvParameter pname,const GLfloat * input,GLfixed * output)2447 void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
2448 {
2449 if (IsTextureEnvEnumParameter(pname))
2450 {
2451 ConvertGLenumValue(input[0], output);
2452 return;
2453 }
2454
2455 switch (pname)
2456 {
2457 case TextureEnvParameter::RgbScale:
2458 case TextureEnvParameter::AlphaScale:
2459 output[0] = FloatToFixed(input[0]);
2460 break;
2461 case TextureEnvParameter::Color:
2462 for (int i = 0; i < 4; i++)
2463 {
2464 output[i] = FloatToFixed(input[i]);
2465 }
2466 break;
2467 default:
2468 UNREACHABLE();
2469 break;
2470 }
2471 }
2472
SetTextureEnv(unsigned int unit,GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,const GLfloat * params)2473 void SetTextureEnv(unsigned int unit,
2474 GLES1State *state,
2475 TextureEnvTarget target,
2476 TextureEnvParameter pname,
2477 const GLfloat *params)
2478 {
2479 TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2480 GLenum asEnum = ConvertToGLenum(params[0]);
2481
2482 switch (target)
2483 {
2484 case TextureEnvTarget::Env:
2485 switch (pname)
2486 {
2487 case TextureEnvParameter::Mode:
2488 env.mode = FromGLenum<TextureEnvMode>(asEnum);
2489 break;
2490 case TextureEnvParameter::CombineRgb:
2491 env.combineRgb = FromGLenum<TextureCombine>(asEnum);
2492 break;
2493 case TextureEnvParameter::CombineAlpha:
2494 env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
2495 break;
2496 case TextureEnvParameter::Src0Rgb:
2497 env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
2498 break;
2499 case TextureEnvParameter::Src1Rgb:
2500 env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
2501 break;
2502 case TextureEnvParameter::Src2Rgb:
2503 env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
2504 break;
2505 case TextureEnvParameter::Src0Alpha:
2506 env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
2507 break;
2508 case TextureEnvParameter::Src1Alpha:
2509 env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
2510 break;
2511 case TextureEnvParameter::Src2Alpha:
2512 env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
2513 break;
2514 case TextureEnvParameter::Op0Rgb:
2515 env.op0Rgb = FromGLenum<TextureOp>(asEnum);
2516 break;
2517 case TextureEnvParameter::Op1Rgb:
2518 env.op1Rgb = FromGLenum<TextureOp>(asEnum);
2519 break;
2520 case TextureEnvParameter::Op2Rgb:
2521 env.op2Rgb = FromGLenum<TextureOp>(asEnum);
2522 break;
2523 case TextureEnvParameter::Op0Alpha:
2524 env.op0Alpha = FromGLenum<TextureOp>(asEnum);
2525 break;
2526 case TextureEnvParameter::Op1Alpha:
2527 env.op1Alpha = FromGLenum<TextureOp>(asEnum);
2528 break;
2529 case TextureEnvParameter::Op2Alpha:
2530 env.op2Alpha = FromGLenum<TextureOp>(asEnum);
2531 break;
2532 case TextureEnvParameter::Color:
2533 env.color = ColorF::fromData(params);
2534 break;
2535 case TextureEnvParameter::RgbScale:
2536 env.rgbScale = params[0];
2537 break;
2538 case TextureEnvParameter::AlphaScale:
2539 env.alphaScale = params[0];
2540 break;
2541 default:
2542 UNREACHABLE();
2543 break;
2544 }
2545 break;
2546 case TextureEnvTarget::PointSprite:
2547 switch (pname)
2548 {
2549 case TextureEnvParameter::PointCoordReplace:
2550 env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
2551 break;
2552 default:
2553 UNREACHABLE();
2554 break;
2555 }
2556 break;
2557 default:
2558 UNREACHABLE();
2559 break;
2560 }
2561 }
2562
GetTextureEnv(unsigned int unit,const GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,GLfloat * params)2563 void GetTextureEnv(unsigned int unit,
2564 const GLES1State *state,
2565 TextureEnvTarget target,
2566 TextureEnvParameter pname,
2567 GLfloat *params)
2568 {
2569 const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2570
2571 switch (target)
2572 {
2573 case TextureEnvTarget::Env:
2574 switch (pname)
2575 {
2576 case TextureEnvParameter::Mode:
2577 ConvertPackedEnum(env.mode, params);
2578 break;
2579 case TextureEnvParameter::CombineRgb:
2580 ConvertPackedEnum(env.combineRgb, params);
2581 break;
2582 case TextureEnvParameter::CombineAlpha:
2583 ConvertPackedEnum(env.combineAlpha, params);
2584 break;
2585 case TextureEnvParameter::Src0Rgb:
2586 ConvertPackedEnum(env.src0Rgb, params);
2587 break;
2588 case TextureEnvParameter::Src1Rgb:
2589 ConvertPackedEnum(env.src1Rgb, params);
2590 break;
2591 case TextureEnvParameter::Src2Rgb:
2592 ConvertPackedEnum(env.src2Rgb, params);
2593 break;
2594 case TextureEnvParameter::Src0Alpha:
2595 ConvertPackedEnum(env.src0Alpha, params);
2596 break;
2597 case TextureEnvParameter::Src1Alpha:
2598 ConvertPackedEnum(env.src1Alpha, params);
2599 break;
2600 case TextureEnvParameter::Src2Alpha:
2601 ConvertPackedEnum(env.src2Alpha, params);
2602 break;
2603 case TextureEnvParameter::Op0Rgb:
2604 ConvertPackedEnum(env.op0Rgb, params);
2605 break;
2606 case TextureEnvParameter::Op1Rgb:
2607 ConvertPackedEnum(env.op1Rgb, params);
2608 break;
2609 case TextureEnvParameter::Op2Rgb:
2610 ConvertPackedEnum(env.op2Rgb, params);
2611 break;
2612 case TextureEnvParameter::Op0Alpha:
2613 ConvertPackedEnum(env.op0Alpha, params);
2614 break;
2615 case TextureEnvParameter::Op1Alpha:
2616 ConvertPackedEnum(env.op1Alpha, params);
2617 break;
2618 case TextureEnvParameter::Op2Alpha:
2619 ConvertPackedEnum(env.op2Alpha, params);
2620 break;
2621 case TextureEnvParameter::Color:
2622 env.color.writeData(params);
2623 break;
2624 case TextureEnvParameter::RgbScale:
2625 *params = env.rgbScale;
2626 break;
2627 case TextureEnvParameter::AlphaScale:
2628 *params = env.alphaScale;
2629 break;
2630 default:
2631 UNREACHABLE();
2632 break;
2633 }
2634 break;
2635 case TextureEnvTarget::PointSprite:
2636 switch (pname)
2637 {
2638 case TextureEnvParameter::PointCoordReplace:
2639 *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
2640 break;
2641 default:
2642 UNREACHABLE();
2643 break;
2644 }
2645 break;
2646 default:
2647 UNREACHABLE();
2648 break;
2649 }
2650 }
2651
GetPointParameterCount(PointParameter pname)2652 unsigned int GetPointParameterCount(PointParameter pname)
2653 {
2654 switch (pname)
2655 {
2656 case PointParameter::PointSizeMin:
2657 case PointParameter::PointSizeMax:
2658 case PointParameter::PointFadeThresholdSize:
2659 return 1;
2660 case PointParameter::PointDistanceAttenuation:
2661 return 3;
2662 default:
2663 return 0;
2664 }
2665 }
2666
SetPointParameter(GLES1State * state,PointParameter pname,const GLfloat * params)2667 void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
2668 {
2669
2670 PointParameters &pointParams = state->pointParameters();
2671
2672 switch (pname)
2673 {
2674 case PointParameter::PointSizeMin:
2675 pointParams.pointSizeMin = params[0];
2676 break;
2677 case PointParameter::PointSizeMax:
2678 pointParams.pointSizeMax = params[0];
2679 break;
2680 case PointParameter::PointFadeThresholdSize:
2681 pointParams.pointFadeThresholdSize = params[0];
2682 break;
2683 case PointParameter::PointDistanceAttenuation:
2684 for (unsigned int i = 0; i < 3; i++)
2685 {
2686 pointParams.pointDistanceAttenuation[i] = params[i];
2687 }
2688 break;
2689 default:
2690 UNREACHABLE();
2691 }
2692 }
2693
GetPointParameter(const GLES1State * state,PointParameter pname,GLfloat * params)2694 void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
2695 {
2696 const PointParameters &pointParams = state->pointParameters();
2697
2698 switch (pname)
2699 {
2700 case PointParameter::PointSizeMin:
2701 params[0] = pointParams.pointSizeMin;
2702 break;
2703 case PointParameter::PointSizeMax:
2704 params[0] = pointParams.pointSizeMax;
2705 break;
2706 case PointParameter::PointFadeThresholdSize:
2707 params[0] = pointParams.pointFadeThresholdSize;
2708 break;
2709 case PointParameter::PointDistanceAttenuation:
2710 for (unsigned int i = 0; i < 3; i++)
2711 {
2712 params[i] = pointParams.pointDistanceAttenuation[i];
2713 }
2714 break;
2715 default:
2716 UNREACHABLE();
2717 }
2718 }
2719
SetPointSize(GLES1State * state,GLfloat size)2720 void SetPointSize(GLES1State *state, GLfloat size)
2721 {
2722 PointParameters ¶ms = state->pointParameters();
2723 params.pointSize = size;
2724 }
2725
GetPointSize(GLES1State * state,GLfloat * sizeOut)2726 void GetPointSize(GLES1State *state, GLfloat *sizeOut)
2727 {
2728 const PointParameters ¶ms = state->pointParameters();
2729 *sizeOut = params.pointSize;
2730 }
2731
GetTexParameterCount(GLenum pname)2732 unsigned int GetTexParameterCount(GLenum pname)
2733 {
2734 switch (pname)
2735 {
2736 case GL_TEXTURE_CROP_RECT_OES:
2737 case GL_TEXTURE_BORDER_COLOR:
2738 return 4;
2739 case GL_TEXTURE_MAG_FILTER:
2740 case GL_TEXTURE_MIN_FILTER:
2741 case GL_TEXTURE_WRAP_S:
2742 case GL_TEXTURE_WRAP_T:
2743 case GL_TEXTURE_USAGE_ANGLE:
2744 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2745 case GL_TEXTURE_IMMUTABLE_FORMAT:
2746 case GL_TEXTURE_WRAP_R:
2747 case GL_TEXTURE_IMMUTABLE_LEVELS:
2748 case GL_TEXTURE_SWIZZLE_R:
2749 case GL_TEXTURE_SWIZZLE_G:
2750 case GL_TEXTURE_SWIZZLE_B:
2751 case GL_TEXTURE_SWIZZLE_A:
2752 case GL_TEXTURE_BASE_LEVEL:
2753 case GL_TEXTURE_MAX_LEVEL:
2754 case GL_TEXTURE_MIN_LOD:
2755 case GL_TEXTURE_MAX_LOD:
2756 case GL_TEXTURE_COMPARE_MODE:
2757 case GL_TEXTURE_COMPARE_FUNC:
2758 case GL_TEXTURE_SRGB_DECODE_EXT:
2759 case GL_DEPTH_STENCIL_TEXTURE_MODE:
2760 case GL_TEXTURE_NATIVE_ID_ANGLE:
2761 return 1;
2762 default:
2763 return 0;
2764 }
2765 }
2766
2767 } // namespace gl
2768
2769 namespace egl
2770 {
2771
QueryConfigAttrib(const Config * config,EGLint attribute,EGLint * value)2772 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
2773 {
2774 ASSERT(config != nullptr);
2775 switch (attribute)
2776 {
2777 case EGL_BUFFER_SIZE:
2778 *value = config->bufferSize;
2779 break;
2780 case EGL_ALPHA_SIZE:
2781 *value = config->alphaSize;
2782 break;
2783 case EGL_BLUE_SIZE:
2784 *value = config->blueSize;
2785 break;
2786 case EGL_GREEN_SIZE:
2787 *value = config->greenSize;
2788 break;
2789 case EGL_RED_SIZE:
2790 *value = config->redSize;
2791 break;
2792 case EGL_DEPTH_SIZE:
2793 *value = config->depthSize;
2794 break;
2795 case EGL_STENCIL_SIZE:
2796 *value = config->stencilSize;
2797 break;
2798 case EGL_CONFIG_CAVEAT:
2799 *value = config->configCaveat;
2800 break;
2801 case EGL_CONFIG_ID:
2802 *value = config->configID;
2803 break;
2804 case EGL_LEVEL:
2805 *value = config->level;
2806 break;
2807 case EGL_NATIVE_RENDERABLE:
2808 *value = config->nativeRenderable;
2809 break;
2810 case EGL_NATIVE_VISUAL_ID:
2811 *value = config->nativeVisualID;
2812 break;
2813 case EGL_NATIVE_VISUAL_TYPE:
2814 *value = config->nativeVisualType;
2815 break;
2816 case EGL_SAMPLES:
2817 *value = config->samples;
2818 break;
2819 case EGL_SAMPLE_BUFFERS:
2820 *value = config->sampleBuffers;
2821 break;
2822 case EGL_SURFACE_TYPE:
2823 *value = config->surfaceType;
2824 break;
2825 case EGL_TRANSPARENT_TYPE:
2826 *value = config->transparentType;
2827 break;
2828 case EGL_TRANSPARENT_BLUE_VALUE:
2829 *value = config->transparentBlueValue;
2830 break;
2831 case EGL_TRANSPARENT_GREEN_VALUE:
2832 *value = config->transparentGreenValue;
2833 break;
2834 case EGL_TRANSPARENT_RED_VALUE:
2835 *value = config->transparentRedValue;
2836 break;
2837 case EGL_BIND_TO_TEXTURE_RGB:
2838 *value = config->bindToTextureRGB;
2839 break;
2840 case EGL_BIND_TO_TEXTURE_RGBA:
2841 *value = config->bindToTextureRGBA;
2842 break;
2843 case EGL_MIN_SWAP_INTERVAL:
2844 *value = config->minSwapInterval;
2845 break;
2846 case EGL_MAX_SWAP_INTERVAL:
2847 *value = config->maxSwapInterval;
2848 break;
2849 case EGL_LUMINANCE_SIZE:
2850 *value = config->luminanceSize;
2851 break;
2852 case EGL_ALPHA_MASK_SIZE:
2853 *value = config->alphaMaskSize;
2854 break;
2855 case EGL_COLOR_BUFFER_TYPE:
2856 *value = config->colorBufferType;
2857 break;
2858 case EGL_RENDERABLE_TYPE:
2859 *value = config->renderableType;
2860 break;
2861 case EGL_MATCH_NATIVE_PIXMAP:
2862 *value = false;
2863 UNIMPLEMENTED();
2864 break;
2865 case EGL_CONFORMANT:
2866 *value = config->conformant;
2867 break;
2868 case EGL_MAX_PBUFFER_WIDTH:
2869 *value = config->maxPBufferWidth;
2870 break;
2871 case EGL_MAX_PBUFFER_HEIGHT:
2872 *value = config->maxPBufferHeight;
2873 break;
2874 case EGL_MAX_PBUFFER_PIXELS:
2875 *value = config->maxPBufferPixels;
2876 break;
2877 case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
2878 *value = config->optimalOrientation;
2879 break;
2880 case EGL_COLOR_COMPONENT_TYPE_EXT:
2881 *value = config->colorComponentType;
2882 break;
2883 case EGL_RECORDABLE_ANDROID:
2884 *value = config->recordable;
2885 break;
2886 default:
2887 UNREACHABLE();
2888 break;
2889 }
2890 }
2891
QueryContextAttrib(const gl::Context * context,EGLint attribute,EGLint * value)2892 void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
2893 {
2894 switch (attribute)
2895 {
2896 case EGL_CONFIG_ID:
2897 *value = context->getConfig()->configID;
2898 break;
2899 case EGL_CONTEXT_CLIENT_TYPE:
2900 *value = context->getClientType();
2901 break;
2902 case EGL_CONTEXT_CLIENT_VERSION:
2903 *value = context->getClientMajorVersion();
2904 break;
2905 case EGL_RENDER_BUFFER:
2906 *value = context->getRenderBuffer();
2907 break;
2908 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2909 *value = context->isRobustResourceInitEnabled();
2910 break;
2911 default:
2912 UNREACHABLE();
2913 break;
2914 }
2915 }
2916
QuerySurfaceAttrib(const Surface * surface,EGLint attribute,EGLint * value)2917 void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value)
2918 {
2919 switch (attribute)
2920 {
2921 case EGL_GL_COLORSPACE:
2922 *value = surface->getGLColorspace();
2923 break;
2924 case EGL_VG_ALPHA_FORMAT:
2925 *value = surface->getVGAlphaFormat();
2926 break;
2927 case EGL_VG_COLORSPACE:
2928 *value = surface->getVGColorspace();
2929 break;
2930 case EGL_CONFIG_ID:
2931 *value = surface->getConfig()->configID;
2932 break;
2933 case EGL_HEIGHT:
2934 *value = surface->getHeight();
2935 break;
2936 case EGL_HORIZONTAL_RESOLUTION:
2937 *value = surface->getHorizontalResolution();
2938 break;
2939 case EGL_LARGEST_PBUFFER:
2940 // The EGL spec states that value is not written if the surface is not a pbuffer
2941 if (surface->getType() == EGL_PBUFFER_BIT)
2942 {
2943 *value = surface->getLargestPbuffer();
2944 }
2945 break;
2946 case EGL_MIPMAP_TEXTURE:
2947 // The EGL spec states that value is not written if the surface is not a pbuffer
2948 if (surface->getType() == EGL_PBUFFER_BIT)
2949 {
2950 *value = surface->getMipmapTexture();
2951 }
2952 break;
2953 case EGL_MIPMAP_LEVEL:
2954 // The EGL spec states that value is not written if the surface is not a pbuffer
2955 if (surface->getType() == EGL_PBUFFER_BIT)
2956 {
2957 *value = surface->getMipmapLevel();
2958 }
2959 break;
2960 case EGL_MULTISAMPLE_RESOLVE:
2961 *value = surface->getMultisampleResolve();
2962 break;
2963 case EGL_PIXEL_ASPECT_RATIO:
2964 *value = surface->getPixelAspectRatio();
2965 break;
2966 case EGL_RENDER_BUFFER:
2967 *value = surface->getRenderBuffer();
2968 break;
2969 case EGL_SWAP_BEHAVIOR:
2970 *value = surface->getSwapBehavior();
2971 break;
2972 case EGL_TEXTURE_FORMAT:
2973 // The EGL spec states that value is not written if the surface is not a pbuffer
2974 if (surface->getType() == EGL_PBUFFER_BIT)
2975 {
2976 *value = ToEGLenum(surface->getTextureFormat());
2977 }
2978 break;
2979 case EGL_TEXTURE_TARGET:
2980 // The EGL spec states that value is not written if the surface is not a pbuffer
2981 if (surface->getType() == EGL_PBUFFER_BIT)
2982 {
2983 *value = surface->getTextureTarget();
2984 }
2985 break;
2986 case EGL_VERTICAL_RESOLUTION:
2987 *value = surface->getVerticalResolution();
2988 break;
2989 case EGL_WIDTH:
2990 *value = surface->getWidth();
2991 break;
2992 case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
2993 *value = surface->isPostSubBufferSupported();
2994 break;
2995 case EGL_FIXED_SIZE_ANGLE:
2996 *value = surface->isFixedSize();
2997 break;
2998 case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
2999 *value = surface->flexibleSurfaceCompatibilityRequested();
3000 break;
3001 case EGL_SURFACE_ORIENTATION_ANGLE:
3002 *value = surface->getOrientation();
3003 break;
3004 case EGL_DIRECT_COMPOSITION_ANGLE:
3005 *value = surface->directComposition();
3006 break;
3007 case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
3008 *value = surface->isRobustResourceInitEnabled();
3009 break;
3010 case EGL_TIMESTAMPS_ANDROID:
3011 *value = surface->isTimestampsEnabled();
3012 break;
3013 default:
3014 UNREACHABLE();
3015 break;
3016 }
3017 }
3018
SetSurfaceAttrib(Surface * surface,EGLint attribute,EGLint value)3019 void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
3020 {
3021 switch (attribute)
3022 {
3023 case EGL_MIPMAP_LEVEL:
3024 surface->setMipmapLevel(value);
3025 break;
3026 case EGL_MULTISAMPLE_RESOLVE:
3027 surface->setMultisampleResolve(value);
3028 break;
3029 case EGL_SWAP_BEHAVIOR:
3030 surface->setSwapBehavior(value);
3031 break;
3032 case EGL_WIDTH:
3033 surface->setFixedWidth(value);
3034 break;
3035 case EGL_HEIGHT:
3036 surface->setFixedHeight(value);
3037 break;
3038 case EGL_TIMESTAMPS_ANDROID:
3039 surface->setTimestampsEnabled(value != EGL_FALSE);
3040 break;
3041 default:
3042 UNREACHABLE();
3043 break;
3044 }
3045 }
3046
GetSyncAttrib(Display * display,Sync * sync,EGLint attribute,EGLint * value)3047 Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value)
3048 {
3049 switch (attribute)
3050 {
3051 case EGL_SYNC_TYPE_KHR:
3052 *value = sync->getType();
3053 return NoError();
3054
3055 case EGL_SYNC_STATUS_KHR:
3056 return sync->getStatus(display, value);
3057
3058 case EGL_SYNC_CONDITION_KHR:
3059 *value = sync->getCondition();
3060 return NoError();
3061
3062 default:
3063 break;
3064 }
3065
3066 UNREACHABLE();
3067 return NoError();
3068 }
3069
3070 } // namespace egl
3071