• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// This file specifies which functions should be attached to GrGLInterface
2// for a given standard (OpenGL, OpenGL ES, etc). It allows specifing
3// how and when to attach them (e.g. only if an extension is present).
4// It is used for both the assemble and validate step.
5//
6// To regenerate the Assemble/Validate code after editing this file, execute:
7//
8//   make -C tools/gpu/gl/interface generate
9//
10// Currently it assumes the minimum versions:
11//   - GL: 2.0
12//   - GLES: 2.0
13//   - WebGL: [WIP] 1.0
14//
15// http://web.eecs.umich.edu/~sugih/courses/eecs487/common/notes/APITables.xml
16// is a handy reference comparing GL and GLES API
17[
18  {
19    "GL":    [{"ext": "<core>"}],
20    "GLES":  [{"ext": "<core>"}],
21    "WebGL": [{"ext": "<core>"}],
22
23    "functions": [
24      "ActiveTexture", "AttachShader", "BindAttribLocation", "BindBuffer",
25      "BindTexture", "BlendColor", "BlendEquation", "BlendFunc",
26      "BufferData", "BufferSubData", "Clear", "ClearColor",
27      "ClearStencil", "ColorMask", "CompileShader", "CompressedTexImage2D",
28      "CompressedTexSubImage2D", "CopyTexSubImage2D", "CreateProgram", "CreateShader",
29      "CullFace", "DeleteBuffers", "DeleteProgram",
30      "DeleteShader", "DeleteTextures", "DepthMask", "Disable",
31      "DisableVertexAttribArray", "DrawArrays", "DrawElements", "Enable",
32      "EnableVertexAttribArray", "Finish", "Flush",
33      "FrontFace", "GenBuffers",
34      "GenTextures", "GetBufferParameteriv", "GetError",
35      "GetIntegerv", "GetProgramInfoLog",
36      "GetProgramiv", "GetShaderInfoLog",
37      "GetShaderiv", "GetString",
38      "GetUniformLocation", "IsTexture", "LineWidth", "LinkProgram", "PixelStorei",
39      "ReadPixels", "Scissor", "ShaderSource", "StencilFunc",
40      "StencilFuncSeparate", "StencilMask", "StencilMaskSeparate", "StencilOp",
41      "StencilOpSeparate", "TexImage2D", "TexParameterf", "TexParameterfv", "TexParameteri",
42      "TexParameteriv", "TexSubImage2D", "Uniform1f", "Uniform1fv", "Uniform1i", "Uniform1iv",
43      "Uniform2f", "Uniform2fv", "Uniform2i", "Uniform2iv", "Uniform3f", "Uniform3fv", "Uniform3i",
44      "Uniform3iv", "Uniform4f", "Uniform4fv", "Uniform4i", "Uniform4iv", "UniformMatrix2fv",
45      "UniformMatrix3fv", "UniformMatrix4fv", "UseProgram", "VertexAttrib1f",
46      "VertexAttrib2fv", "VertexAttrib3fv", "VertexAttrib4fv", "VertexAttribPointer",
47      "Viewport",
48    ],
49  },
50  { // GL exclusive core functions
51    "GL":    [{"ext": "<core>"}],
52    "GLES":  null,
53
54    "functions": [
55      "DrawBuffer", "PolygonMode",
56    ],
57  },
58  {
59    "GL":    [{"min_version": [3, 0], "ext": "<core>"}],
60    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
61    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
62
63    "functions": [
64      "GetStringi",
65    ]
66  },
67  {
68    "GL":    [{"min_version": [4, 2], "ext": "<core>"}],
69    "GLES":  [{"min_version": [3, 1], "ext": "<core>"}],
70    "WebGL": null,
71
72    "functions": [
73      "MemoryBarrier",
74    ],
75    // TODO: Remove 'optional' once Chrome sets this function in the interface.
76    "optional": [
77      "MemoryBarrier",
78    ]
79  },
80
81  {
82    "GL":    [{"ext": "<core>"}],
83    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
84              {/*    else if      */  "ext": "GL_OES_vertex_array_object"}],
85    "WebGL": [{"min_version": [2, 0], "ext": "<core>"},
86              {/*    else if      */  "ext": "GL_OES_vertex_array_object"},
87              {/*    else if      */  "ext": "OES_vertex_array_object"}],
88
89    // WebGL uses createVertexArray instead of genVertexArrays, but Emscripten
90    // creates an alias called genVertexArray which papers over this difference.
91    "functions": [
92      "BindVertexArray", "DeleteVertexArrays", "GenVertexArrays",
93    ],
94  },
95
96  {
97    "GL":    [{"min_version": [4, 0], "ext": "<core>"},
98              {/*    else if      */  "ext": "GL_ARB_tessellation_shader"}],
99    "GLES":  [{"min_version": [3, 2], "ext": "<core>"},
100              {/*    else if      */  "ext": "GL_OES_tessellation_shader"}],
101    "WebGL": null,
102
103    "functions": [
104      "PatchParameteri",
105    ],
106    // FIXME: Make this method non-optional once Chrome starts adding it to the interface.
107    "optional": [
108      "PatchParameteri",
109    ]
110  },
111
112  {
113    "GL":    [{"min_version": [3, 0], "ext": "<core>"}],
114    "GLES":  [{"min_version": [3, 0], "ext": "GL_EXT_blend_func_extended"}],
115    "WebGL": null,
116
117    "functions": [
118      "BindFragDataLocation",
119    ],
120  },
121  {
122    "GL":    [{"min_version": [3, 3], "ext": "<core>"},
123              {/*    else if      */  "ext": "GL_ARB_blend_func_extended"}],
124    "GLES":  [{"min_version": [3, 0], "ext": "GL_EXT_blend_func_extended"}],
125    "WebGL": null,
126
127    "functions": [
128      "BindFragDataLocationIndexed",
129    ],
130  },
131
132  {
133    "GL":    [{"ext": "GL_KHR_blend_equation_advanced"},
134              {"ext": "GL_NV_blend_equation_advanced"}],
135    "GLES":  [{"ext": "GL_KHR_blend_equation_advanced"},
136              {"ext": "GL_NV_blend_equation_advanced"}],
137    "WebGL": null,
138
139    "functions": [
140      "BlendBarrier",
141    ],
142  },
143
144  {
145    "GL":    [{"min_version": [4, 4], "ext": "<core>"},
146              {/*    else if      */  "ext": "GL_ARB_clear_texture"}],
147    "GLES":  [{"ext": "GL_EXT_clear_texture", "suffix": "EXT"}],
148    "WebGL": null,
149
150    "functions": [
151      "ClearTexImage", "ClearTexSubImage",
152    ],
153    // https://bugs.chromium.org/p/skia/issues/detail?id=8913
154    "optional": [
155      "ClearTexImage", "ClearTexSubImage",
156    ]
157  },
158
159  {
160    "GL":    [{"min_version": [3, 1], "ext": "<core>"},
161              {/*    else if      */  "ext": "GL_ARB_draw_instanced"},
162              {/*    else if      */  "ext": "GL_EXT_draw_instanced"}],
163    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
164              {/*    else if      */  "ext": "GL_EXT_draw_instanced"}],
165    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
166
167    "functions": [
168      "DrawArraysInstanced", "DrawElementsInstanced",
169    ]
170  },
171  { // ES 3.0 has glDrawBuffers but not glDrawBuffer
172    "GL":    [{"ext": "<core>"}],
173    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
174    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
175
176    "functions": [
177      "DrawBuffers", "ReadBuffer",
178    ]
179  },
180
181  {
182    "GL":    [{"min_version": [4, 0], "ext": "<core>"},
183              {/*    else if      */  "ext": "GL_ARB_draw_indirect"}],
184    "GLES":  [{"min_version": [3, 1], "ext": "<core>"}],
185    "WebGL": null,
186
187    "functions": [
188      "DrawArraysIndirect", "DrawElementsIndirect",
189    ]
190  },
191
192  { // glDrawRangeElements was added to ES in 3.0.
193    "GL":    [{"ext": "<core>"}],
194    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
195    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
196
197    "functions": [
198      "DrawRangeElements",
199    ]
200  },
201
202  {
203    "GL":    [{"min_version": [3, 2], "ext": "<core>"},
204              {/*    else if      */  "ext": "GL_ARB_texture_multisample"}],
205    "GLES":  [{"min_version": [3, 1], "ext": "<core>"}],
206    "WebGL": null,
207
208    "functions": [
209      "GetMultisamplefv",
210    ]
211  },
212
213  // glGetTexLevelParameteriv was added to ES in 3.1.
214  {
215    "GL":    [{"ext": "<core>"}],
216    "GLES":  [{"min_version": [3, 1], "ext": "<core>"}],
217    "WebGL": null,
218
219    "functions": [
220      "GetTexLevelParameteriv",
221    ]
222  },
223
224  {
225    "GL":    [{"min_version": [4, 3], "ext": "<core>"},
226              {/*    else if      */  "ext": "GL_ARB_multi_draw_indirect"}],
227    "GLES":  [{"ext": "GL_EXT_multi_draw_indirect"}],
228    "WebGL": null,
229
230    "functions": [
231      "MultiDrawArraysIndirect", "MultiDrawElementsIndirect",
232    ]
233  },
234
235  {
236    "GL":    [{"min_version": [3, 1], "ext": "<core>"}],
237    "GLES":  [{"min_version": [3, 2], "ext": "<core>"},
238              {/*    else if      */  "ext": "GL_OES_texture_buffer"},
239              {/*    else if      */  "ext": "GL_EXT_texture_buffer"}],
240    "WebGL": null,
241
242    "functions": [
243      "TexBuffer",
244    ]
245  },
246  {
247    "GL":    [{"min_version": [4, 3], "ext": "<core>"}],
248    "GLES":  [{"min_version": [3, 2], "ext": "<core>"},
249              {/*    else if      */  "ext": "GL_OES_texture_buffer"},
250              {/*    else if      */  "ext": "GL_EXT_texture_buffer"}],
251    "WebGL": null,
252
253    "functions": [
254      "TexBufferRange",
255    ]
256  },
257
258    // GL_EXT_texture_storage is part of desktop 4.2
259    // There is a desktop ARB extension and an ES+desktop EXT extension
260  {
261    "GL":    [{"min_version": [4, 2], "ext": "<core>"},
262              {/*    else if      */  "ext": "GL_ARB_texture_storage"},
263              {/*    else if      */  "ext": "GL_EXT_texture_storage"}],
264    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
265              {/*    else if      */  "ext": "GL_EXT_texture_storage"}],
266    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
267
268    "functions": [
269      "TexStorage2D",
270    ]
271  },
272
273  // glTextureBarrier is part of desktop 4.5. There are also ARB and NV extensions.
274  {
275    "GL":    [{"min_version": [4, 5], "ext": "<core>"},
276              {/*    else if      */  "ext": "GL_ARB_texture_barrier"},
277              {/*    else if      */  "ext": "GL_NV_texture_barrier"}],
278    "GLES":  [{"ext": "GL_NV_texture_barrier"}],
279    "WebGL": null,
280
281    "functions": [
282      "TextureBarrier",
283    ]
284  },
285
286  {
287    "GL":    null, // Not supported
288    "GLES":  [{"ext": "GL_EXT_discard_framebuffer"}],
289    "WebGL": null,
290
291    "functions": [
292      "DiscardFramebuffer",
293    ]
294  },
295
296  {
297    "GL":    null, // Not supported
298    "GLES":  [{"ext": "GL_QCOM_tiled_rendering"}],
299    "WebGL": null,
300
301    "functions": [
302      "StartTiling", "EndTiling",
303    ],
304    // https://github.com/flutter/flutter/issues/47164
305    // https://github.com/flutter/flutter/issues/47804
306    "optional": [
307      "StartTiling", "EndTiling",
308    ]
309  },
310
311  {
312    "GL":    [{"min_version": [3, 2], "ext": "<core>"},
313              {/*    else if      */  "ext": "GL_ARB_instanced_arrays"}],
314    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
315              {/*    else if      */  "ext": "GL_EXT_instanced_arrays"}],
316    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
317
318    "functions": [
319      "VertexAttribDivisor",
320    ]
321  },
322  {
323    "GL":    [{"min_version": [3, 0], "ext": "<core>"}],
324    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
325    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
326
327    "functions": [
328      "VertexAttribIPointer",
329    ]
330  },
331
332  // FrameBuffer Object (FBO) related calls
333  {
334    "GL":    [{"min_version": [3, 0], "ext": "<core>"},
335              {/*    else if      */  "ext": "GL_ARB_framebuffer_object"},
336              {/*    else if      */  "ext": "GL_EXT_framebuffer_object"}],
337    "GLES":  [{"ext": "<core>"}], // These are all in ES 2.0 and above
338    "WebGL": [{"ext": "<core>"}],
339
340    "functions": [
341      "BindFramebuffer", "BindRenderbuffer", "CheckFramebufferStatus",
342      "DeleteFramebuffers", "DeleteRenderbuffers", "FramebufferRenderbuffer",
343      "FramebufferTexture2D", "GenFramebuffers", "GenRenderbuffers", "GenerateMipmap",
344      "GetFramebufferAttachmentParameteriv", "GetRenderbufferParameteriv",
345      "RenderbufferStorage",
346    ],
347  },
348  {
349    "GL":    [{"min_version": [3, 0], "ext": "<core>"},
350              {/*    else if      */  "ext": "GL_ARB_framebuffer_object"},
351              {/*    else if      */  "ext": "GL_EXT_framebuffer_blit"}],
352    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
353              {/*    else if      */  "ext": "GL_CHROMIUM_framebuffer_multisample"},
354              {/*    else if      */  "ext": "GL_ANGLE_framebuffer_blit"}],
355    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
356
357    "functions": [
358      "BlitFramebuffer",
359    ],
360  },
361  {
362    "GL":    [{"min_version": [3, 0], "ext": "<core>"},
363              {/*    else if      */  "ext": "GL_ARB_framebuffer_object"},
364              {/*    else if      */  "ext": "GL_EXT_framebuffer_multisample"}],
365    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
366              {/*    else if      */  "ext": "GL_CHROMIUM_framebuffer_multisample"},
367              {/*    else if      */  "ext": "GL_ANGLE_framebuffer_multisample"}],
368    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
369
370    "functions": [
371      "RenderbufferStorageMultisample",
372    ],
373  },
374
375  {
376    "GL":    null,
377    "GLES":  [{"ext": "GL_CHROMIUM_map_sub"}],
378    "WebGL": null,
379
380    "functions": [
381      "MapBufferSubData", "MapTexSubImage2D", "UnmapBufferSubData",
382      "UnmapTexSubImage2D"
383    ],
384  },
385
386  {
387    "GL":    null,
388    "GLES":  [{"ext": "GL_EXT_multisampled_render_to_texture"},
389              {"ext": "GL_IMG_multisampled_render_to_texture"}],
390    "WebGL": null,
391
392    "functions": [
393      "FramebufferTexture2DMultisample",
394    ],
395  },
396  {
397    "GL":    null,
398    "GLES":  [{"ext": "GL_EXT_multisampled_render_to_texture"}],
399    "WebGL": null,
400
401    "hardcode_functions" : [
402      {
403        "ptr_name": "fRenderbufferStorageMultisampleES2EXT",
404        "cast_name": "GrGLRenderbufferStorageMultisampleFn",
405        "get_name": "glRenderbufferStorageMultisampleEXT",
406      }
407    ]
408  },
409  {
410    "GL":    null,
411    "GLES":  [{"ext": "GL_IMG_multisampled_render_to_texture"}],
412    "WebGL": null,
413
414    "hardcode_functions" : [
415      {
416        "ptr_name": "fRenderbufferStorageMultisampleES2EXT",
417        "cast_name": "GrGLRenderbufferStorageMultisampleFn",
418        "get_name": "glRenderbufferStorageMultisampleIMG",
419      }
420    ]
421  },
422  {
423    "GL":    null,
424    "GLES":  [{"ext": "GL_APPLE_framebuffer_multisample"}],
425    "WebGL": null,
426
427    "functions" : ["ResolveMultisampleFramebuffer"],
428    "hardcode_functions" : [
429      {
430        "ptr_name": "fRenderbufferStorageMultisampleES2APPLE",
431        "cast_name": "GrGLRenderbufferStorageMultisampleFn",
432        "get_name": "glRenderbufferStorageMultisampleAPPLE",
433      }
434    ]
435  },
436
437    // There are several APIs for buffer mapping:
438    // ES2 + GL_OES_mapbuffer: MapBufferOES and UnmapBufferOES
439    // ES2 + GL_EXT_map_buffer_range: Adds MapBufferRangeEXT and FlushMappedBufferRangeEXT
440    // ES3: MapBufferRange, FlushMappedBufferRange, and UnmapBuffer are core (so no suffix).
441    //
442    // MapBuffer is not part of ES3, but implementations may still report the OES versions of
443    // MapBuffer and UnmapBuffer, per the older GL_OES_mapbuffer extension. Some implementations
444    // let us mix the newer MapBufferRange with the older UnmapBufferOES, but we've hit others that
445    // don't permit it. Note that in GrGLBuffer, we choose which API to use based on version and
446    // extensions. This code is written so that we never mix OES and non-OES functions.
447  {
448    "GL":    [{"ext": "<core>"}],
449    "GLES":  [{"ext": "GL_OES_mapbuffer"}],
450    "WebGL": null,
451
452    "functions": [
453      "MapBuffer",
454    ],
455  },
456  {
457    "GL":    [{"ext": "<core>"}],
458    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
459              {/*    else if      */  "ext": "GL_OES_mapbuffer"}],
460    "WebGL": null, // explicitly removed https://www.khronos.org/registry/webgl/specs/2.0/#5.14
461
462    "functions": [
463      "UnmapBuffer",
464    ],
465  },
466  {
467    "GL":    [{"min_version": [3, 0], "ext": "<core>"},
468              {/*    else if      */  "ext": "GL_ARB_map_buffer_range"}],
469    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
470              {/*    else if      */  "ext": "GL_EXT_map_buffer_range"}],
471    "WebGL": null, // explicitly removed https://www.khronos.org/registry/webgl/specs/2.0/#5.14
472
473    "functions": [
474      // These functions are added to the 3.0 version of both GLES and GL.
475      "MapBufferRange", "FlushMappedBufferRange",
476    ],
477  },
478
479  {
480    "GL":    [{"ext": "GL_EXT_debug_marker"}],
481    "GLES":  [{"ext": "GL_EXT_debug_marker"}],
482    "WebGL": null,
483
484    "functions": [
485      "InsertEventMarker", "PushGroupMarker", "PopGroupMarker"
486    ],
487  },
488
489  {
490    "GL":    [{"min_version": [4, 3], "ext": "<core>"},
491              {/*    else if      */  "ext": "GL_ARB_program_interface_query"}],
492    "GLES":  [{"min_version": [3, 1], "ext": "<core>"}],
493    "WebGL": null,
494
495    "functions": [
496      "GetProgramResourceLocation",
497    ],
498  },
499
500  {  // It appears that the GL_NV_path_rendering sometimes provides these
501     // functions under the "EXT" extension instead of "NV".
502    "GL":    [{"ext": "GL_NV_path_rendering", "suffix": "EXT"}],
503
504    "GLES":  [{"ext": "GL_CHROMIUM_path_rendering"},
505              {"ext": "GL_NV_path_rendering", "suffix": "EXT"}],
506    "WebGL": null,
507
508    "functions": [
509      "MatrixLoadIdentity", "MatrixLoadf"
510    ],
511  },
512  {
513    "GL":    [{"ext": "GL_NV_path_rendering"}],
514    "GLES":  [{"ext": "GL_CHROMIUM_path_rendering"},
515              {"ext": "GL_NV_path_rendering"}],
516    "WebGL": null,
517
518    "functions": [
519      "CoverFillPath", "CoverFillPathInstanced", "CoverStrokePath",
520      "CoverStrokePathInstanced", "DeletePaths", "GenPaths",
521      "IsPath", "PathCommands", "PathParameterf", "PathParameteri",
522      "PathStencilFunc", "ProgramPathFragmentInputGen", "StencilFillPath",
523      "StencilFillPathInstanced", "StencilStrokePath", "StencilStrokePathInstanced",
524      "StencilThenCoverFillPath", "StencilThenCoverFillPathInstanced",
525      "StencilThenCoverStrokePath", "StencilThenCoverStrokePathInstanced",
526    ],
527    // List of functions that Skia uses, but which have been added since the initial release
528    // of NV_path_rendering driver. We do not want to fail interface validation due to
529    // missing features, we will just not use the extension.
530    // If one updates this list, then update GrGLCaps::hasPathRenderingSupport too.
531    "optional": [
532      "ProgramPathFragmentInputGen", "StencilThenCoverFillPath",
533      "StencilThenCoverFillPathInstanced", "StencilThenCoverStrokePath",
534      "StencilThenCoverStrokePathInstanced",
535    ],
536  },
537  {
538    "GL":    null,
539    "GLES":  [{"ext": "GL_CHROMIUM_path_rendering"}],
540    "WebGL": null,
541
542    "functions": [
543      "BindFragmentInputLocation",
544    ],
545  },
546  {
547    "GL":    [{"ext": "GL_NV_framebuffer_mixed_samples"}],
548    "GLES":  [{"ext": "GL_CHROMIUM_framebuffer_mixed_samples"},
549              {"ext": "GL_NV_framebuffer_mixed_samples"}],
550    "WebGL": null,
551
552    "functions": [
553      "CoverageModulation",
554    ],
555  },
556
557  {
558    "GL":    [{"min_version": [4, 3], "ext": "<core>"},
559              {/*    else if      */  "ext": "GL_KHR_debug", "suffix": ""}],
560    "GLES":  [{"ext": "GL_KHR_debug"}],
561    "WebGL": null,
562
563    // In OpenGL (but not ES), KHR_debug defines these methods to have no suffix.
564    "functions": [
565      "DebugMessageControl", "DebugMessageInsert", "DebugMessageCallback",
566      "GetDebugMessageLog", "PushDebugGroup", "PopDebugGroup", "ObjectLabel",
567    ],
568  },
569
570  {
571    "GL":    null,
572    "GLES":  [{"ext": "GL_CHROMIUM_bind_uniform_location"}],
573    "WebGL": null,
574
575    "functions": [
576      "BindUniformLocation",
577    ],
578  },
579
580  {
581    "GL":    [{"ext": "GL_EXT_window_rectangles"}],
582    "GLES":  [{"ext": "GL_EXT_window_rectangles"}],
583    "WebGL": null,
584
585    "functions": [
586      "WindowRectangles",
587    ],
588  },
589
590  {
591    "GL":    [{"min_version": [3, 2], "ext": "<core>"},
592              {/*    else if      */  "ext": "GL_ARB_sync"}],
593    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
594              {/*    else if      */  "ext": "GL_APPLE_sync"}],
595    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
596
597    "functions": [
598      "ClientWaitSync", "DeleteSync", "FenceSync",
599      "IsSync", "WaitSync"
600    ],
601  },
602
603  {  // getInternalformativ was added in GL 4.2, ES 3.0, and with
604     // extension ARB_internalformat_query
605    "GL":    [{"min_version": [4, 2], "ext": "<core>"},
606              {/*    else if      */  "ext": "GL_ARB_internalformat_query"}],
607    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
608    "WebGL": null,
609
610    "functions": [
611      "GetInternalformativ"
612    ],
613  },
614
615  // GetProgramBinary and ProgramBinary are available with an ES2 extension...
616  {
617    "GL":    [{"min_version": [4, 1], "ext": "<core>"}],
618    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
619              {/*    else if      */  "ext": "GL_OES_get_program_binary"}],
620    "WebGL": null, // explicitly not supported in WebGL 2.0
621
622    "functions": [
623      "GetProgramBinary", "ProgramBinary",
624    ],
625  },
626
627  // ... but the related ProgramParameteri is only in ES3
628  {
629    "GL":    [{"min_version": [4, 1], "ext": "<core>"}],
630    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
631    "WebGL": null, // explicitly not supported in WebGL 2.0
632
633    "functions": [
634      "ProgramParameteri",
635    ],
636  },
637
638  {
639    "GL":    [{"min_version": [3, 2], "ext": "<core>"},
640              {/*    else if      */  "ext": "GL_ARB_sampler_objects"}],
641    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
642    "WebGL":  [{"min_version": [2, 0], "ext": "<core>"}],
643
644    "functions": [
645      "BindSampler", "DeleteSamplers", "GenSamplers",
646      "SamplerParameteri", "SamplerParameteriv",
647    ],
648  },
649
650  {
651    "GL":    [{"ext": "<core>"}],
652    "GLES":  null, // not in ES
653    "WebGL": null,
654
655    "functions": [
656      "GetQueryObjectiv",
657    ],
658  },
659  {
660    "GL":    [{"ext": "<core>"}],
661    "GLES":  [{"min_version": [3, 0], "ext": "<core>"},
662              {/*    else if      */  "ext": "GL_EXT_occlusion_query_boolean"}],
663    "WebGL": null,
664
665    // We only use these in our test tools
666    "test_functions": [
667      "GenQueries", "DeleteQueries", "BeginQuery", "EndQuery",
668      "GetQueryObjectuiv", "GetQueryiv",
669    ]
670  },
671  {
672    "GL":    [{"min_version": [3, 3], "ext": "<core>"},
673              {/*    else if      */  "ext": "GL_ARB_timer_query"},
674              {/*    else if      */  "ext": "GL_EXT_timer_query"}],
675    "GLES":  null,
676    "WebGL": null,
677
678    "functions": [
679      "GetQueryObjecti64v", "GetQueryObjectui64v",
680    ],
681  },
682  {
683    "GL":    [{"min_version": [3, 3], "ext": "<core>"},
684              {/*    else if      */  "ext": "GL_ARB_timer_query"}],
685    "GLES":  null,
686    "WebGL": null,
687
688    "functions": [
689      "QueryCounter",
690    ],
691  },
692
693  {
694    "GL":    [{"min_version": [4, 3], "ext": "<core>"},
695              {/*    else if      */  "ext": "GL_ARB_invalidate_subdata"}],
696    "GLES":  null,
697    "WebGL": null,
698
699    "functions": [
700      "InvalidateBufferData", "InvalidateBufferSubData", "InvalidateTexImage",
701      "InvalidateTexSubImage",
702    ],
703  },
704  {  // ES 3.0 adds the framebuffer functions but not the others.
705    "GL":    [{"min_version": [4, 3], "ext": "<core>"},
706              {/*    else if      */  "ext": "GL_ARB_invalidate_subdata"}],
707    "GLES":  [{"min_version": [3, 0], "ext": "<core>"}],
708    "WebGL": [{"min_version": [2, 0], "ext": "<core>"}],
709
710    "functions": [
711      "InvalidateFramebuffer", "InvalidateSubFramebuffer",
712    ],
713  },
714
715  {
716    "GL":    [{"min_version": [4, 3], "ext": "<core>"},
717              {/*    else if      */  "ext": "GL_ARB_ES2_compatibility"}],
718    "GLES":  [{"ext": "<core>"}],
719    "WebGL": [{"ext": "<core>"}],
720
721    "functions": [
722      "GetShaderPrecisionFormat",
723    ],
724  },
725
726  {
727    "GL":    [{"ext": "GL_NV_fence"}],
728    "GLES":  [{"ext": "GL_NV_fence"}],
729    "WebGL": null,
730
731    "functions": [
732      "DeleteFences", "FinishFence", "GenFences", "SetFence", "TestFence",
733    ],
734  }
735]
736