1 
2 //          Copyright 2018 - 2021 Michael D. Parker
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          http://www.boost.org/LICENSE_1_0.txt)
6 
7 module bindbc.opengl.bind.arb.core_40;
8 
9 import bindbc.loader;
10 import bindbc.opengl.config,
11        bindbc.opengl.context;
12 import bindbc.opengl.bind.types;
13 
14 static if(glSupport >= GLSupport.gl40) {
15     enum has40 = true;
16 }
17 else enum has40 = false;
18 /+
19 // ARB_occlusion_query2
20 version(GL_ARB) enum useARBOcclusionQuery2 = true;
21 else version(GL_ARB_occlusion_query2) enum useARBOcclusionQuery2 = true;
22 else enum useARBOcclusionQuery2 = has33;
23 
24 static if(useARBOcclusionQuery2) {
25     private bool _hasARBOcclusionQuery2;
26     @nogc nothrow bool hasARBOcclusionQuery2() { return _hasARBOcclusionQuery2; }
27 }
28 else enum hasARBOcclusionQuery2 = false;
29 
30 +/
31 // ARB_gpu_shader5
32 version(GL_ARB) enum useARBGPUShader5 = true;
33 else version(GL_ARB_gpu_shader5) enum useARBGPUShader5 = true;
34 else enum useARBGPUShader5 = has40;
35 
36 static if(useARBGPUShader5) {
37     private bool _hasARBGPUShader5;
38     @nogc nothrow bool hasARBGPUShader5() { return _hasARBGPUShader5; }
39 
40     enum : uint {
41         GL_GEOMETRY_SHADER_INVOCATIONS    = 0x887F,
42         GL_MAX_GEOMETRY_SHADER_INVOCATIONS = 0x8E5A,
43         GL_MIN_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5B,
44         GL_MAX_FRAGMENT_INTERPOLATION_OFFSET = 0x8E5C,
45         GL_FRAGMENT_INTERPOLATION_OFFSET_BITS = 0x8E5D,
46     }
47 }
48 else enum hasARBGPUShader5 = false;
49 
50 // ARB_draw_indirect
51 version(GL_ARB) enum useARBDrawIndirect = true;
52 else version(GL_ARB_draw_indirect) enum useARBDrawIndirect = true;
53 else enum useARBDrawIndirect = has40;
54 
55 static if(useARBDrawIndirect) {
56     private bool _hasARBDrawIndirect;
57     @nogc nothrow bool hasARBDrawIndirect() { return _hasARBDrawIndirect; }
58 
59     enum : uint {
60         GL_DRAW_INDIRECT_BUFFER           = 0x8F3F,
61         GL_DRAW_INDIRECT_BUFFER_BINDING   = 0x8F43,
62     }
63 
64     extern(System) @nogc nothrow {
65         alias pglDrawArraysIndirect = void function(GLenum, const(GLvoid)*);
66         alias pglDrawElementsIndirect = void function(GLenum, GLenum, const(GLvoid)*);
67     }
68 
69     __gshared {
70         pglDrawArraysIndirect glDrawArraysIndirect;
71         pglDrawElementsIndirect glDrawElementsIndirect;
72     }
73 
74     private @nogc nothrow
75     bool loadARBDrawIndirect(SharedLib lib, GLSupport contextVersion)
76     {
77         lib.bindGLSymbol(cast(void**)&glDrawArraysIndirect, "glDrawArraysIndirect");
78         lib.bindGLSymbol(cast(void**)&glDrawElementsIndirect, "glDrawElementsIndirect");
79         return resetErrorCountGL();
80     }
81 }
82 else enum hasARBDrawIndirect = false;
83 
84 // ARB_gpu_shader_fp64
85 version(GL_ARB) enum useARBGPUShaderFP64 = true;
86 else version(GL_ARB_gpu_shader_fp64) enum useARBGPUShaderFP64 = true;
87 else enum useARBGPUShaderFP64 = has40;
88 
89 static if(useARBGPUShaderFP64) {
90     private bool _hasARBGPUShaderFP64;
91     @nogc nothrow bool hasARBGPUShaderFP64() { return _hasARBGPUShaderFP64; }
92 
93     enum : uint {
94         GL_DOUBLE_VEC2                    = 0x8FFC,
95         GL_DOUBLE_VEC3                    = 0x8FFD,
96         GL_DOUBLE_VEC4                    = 0x8FFE,
97         GL_DOUBLE_MAT2                    = 0x8F46,
98         GL_DOUBLE_MAT3                    = 0x8F47,
99         GL_DOUBLE_MAT4                    = 0x8F48,
100         GL_DOUBLE_MAT2x3                  = 0x8F49,
101         GL_DOUBLE_MAT2x4                  = 0x8F4A,
102         GL_DOUBLE_MAT3x2                  = 0x8F4B,
103         GL_DOUBLE_MAT3x4                  = 0x8F4C,
104         GL_DOUBLE_MAT4x2                  = 0x8F4D,
105         GL_DOUBLE_MAT4x3                  = 0x8F4E,
106     }
107 
108     extern(System) @nogc nothrow {
109         alias pglUniform1d = void function(GLint,GLdouble);
110         alias pglUniform2d = void function(GLint,GLdouble,GLdouble);
111         alias pglUniform3d = void function(GLint,GLdouble,GLdouble,GLdouble);
112         alias pglUniform4d = void function(GLint,GLdouble,GLdouble,GLdouble,GLdouble);
113         alias pglUniform1dv = void function(GLint,GLsizei,const(GLdouble)*);
114         alias pglUniform2dv = void function(GLint,GLsizei,const(GLdouble)*);
115         alias pglUniform3dv = void function(GLint,GLsizei,const(GLdouble)*);
116         alias pglUniform4dv = void function(GLint,GLsizei,const(GLdouble)*);
117         alias pglUniformMatrix2dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
118         alias pglUniformMatrix3dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
119         alias pglUniformMatrix4dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
120         alias pglUniformMatrix2x3dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
121         alias pglUniformMatrix2x4dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
122         alias pglUniformMatrix3x2dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
123         alias pglUniformMatrix3x4dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
124         alias pglUniformMatrix4x2dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
125         alias pglUniformMatrix4x3dv = void function(GLint,GLsizei,GLboolean,const(GLdouble)*);
126         alias pglGetUniformdv = void function(GLuint,GLint,GLdouble*);
127     }
128 
129     __gshared {
130         pglUniform1d glUniform1d;
131         pglUniform2d glUniform2d;
132         pglUniform3d glUniform3d;
133         pglUniform4d glUniform4d;
134         pglUniform1dv glUniform1dv;
135         pglUniform2dv glUniform2dv;
136         pglUniform3dv glUniform3dv;
137         pglUniform4dv glUniform4dv;
138         pglUniformMatrix2dv glUniformMatrix2dv;
139         pglUniformMatrix3dv glUniformMatrix3dv;
140         pglUniformMatrix4dv glUniformMatrix4dv;
141         pglUniformMatrix2x3dv glUniformMatrix2x3dv;
142         pglUniformMatrix2x4dv glUniformMatrix2x4dv;
143         pglUniformMatrix3x2dv glUniformMatrix3x2dv;
144         pglUniformMatrix3x4dv glUniformMatrix3x4dv;
145         pglUniformMatrix4x2dv glUniformMatrix4x2dv;
146         pglUniformMatrix4x3dv glUniformMatrix4x3dv;
147         pglGetUniformdv glGetUniformdv;
148     }
149 
150     private @nogc nothrow
151     bool loadARBGPUShaderFP64(SharedLib lib, GLSupport contextVersion)
152     {
153         lib.bindGLSymbol(cast(void**)&glUniform1d,"glUniform1d");
154         lib.bindGLSymbol(cast(void**)&glUniform2d,"glUniform2d");
155         lib.bindGLSymbol(cast(void**)&glUniform3d,"glUniform3d");
156         lib.bindGLSymbol(cast(void**)&glUniform4d,"glUniform4d");
157         lib.bindGLSymbol(cast(void**)&glUniform1dv,"glUniform1dv");
158         lib.bindGLSymbol(cast(void**)&glUniform2dv,"glUniform2dv");
159         lib.bindGLSymbol(cast(void**)&glUniform3dv,"glUniform3dv");
160         lib.bindGLSymbol(cast(void**)&glUniform4dv,"glUniform4dv");
161         lib.bindGLSymbol(cast(void**)&glUniformMatrix2dv,"glUniformMatrix2dv");
162         lib.bindGLSymbol(cast(void**)&glUniformMatrix3dv,"glUniformMatrix3dv");
163         lib.bindGLSymbol(cast(void**)&glUniformMatrix4dv,"glUniformMatrix4dv");
164         lib.bindGLSymbol(cast(void**)&glUniformMatrix2x3dv,"glUniformMatrix2x3dv");
165         lib.bindGLSymbol(cast(void**)&glUniformMatrix2x4dv,"glUniformMatrix2x4dv");
166         lib.bindGLSymbol(cast(void**)&glUniformMatrix3x2dv,"glUniformMatrix3x2dv");
167         lib.bindGLSymbol(cast(void**)&glUniformMatrix3x4dv,"glUniformMatrix3x4dv");
168         lib.bindGLSymbol(cast(void**)&glUniformMatrix4x2dv,"glUniformMatrix4x2dv");
169         lib.bindGLSymbol(cast(void**)&glUniformMatrix4x3dv,"glUniformMatrix4x3dv");
170         lib.bindGLSymbol(cast(void**)&glGetUniformdv,"glGetUniformdv");
171         return resetErrorCountGL();
172     }
173 }
174 else enum hasARBGPUShaderFP64 = false;
175 
176 // ARB_shader_subroutine
177 version(GL_ARB) enum useARBShaderSubroutine = true;
178 else version(GL_ARB_shader_subroutine) enum useARBShaderSubroutine = true;
179 else enum useARBShaderSubroutine = has40;
180 
181 static if(useARBShaderSubroutine) {
182     private bool _hasARBShaderSubroutine;
183     @nogc nothrow bool hasARBShaderSubroutine() { return _hasARBShaderSubroutine; }
184 
185     enum : uint {
186         GL_ACTIVE_SUBROUTINES             = 0x8DE5,
187         GL_ACTIVE_SUBROUTINE_UNIFORMS     = 0x8DE6,
188         GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS = 0x8E47,
189         GL_ACTIVE_SUBROUTINE_MAX_LENGTH   = 0x8E48,
190         GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH = 0x8E49,
191         GL_MAX_SUBROUTINES                = 0x8DE7,
192         GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS = 0x8DE8,
193         GL_NUM_COMPATIBLE_SUBROUTINES     = 0x8E4A,
194         GL_COMPATIBLE_SUBROUTINES         = 0x8E4B,
195     }
196 
197     extern(System) @nogc nothrow {
198         alias pglGetSubroutineUniformLocation = GLint function(GLuint, GLenum, const(GLchar)*);
199         alias pglGetSubroutineIndex = GLuint function(GLuint, GLenum, const(GLchar)*);
200         alias pglGetActiveSubroutineUniformiv = void function(GLuint, GLenum, GLuint, GLenum, GLint*);
201         alias pglGetActiveSubroutineUniformName = void function(GLuint, GLenum, GLuint, GLsizei, GLsizei*, GLchar*);
202         alias pglGetActiveSubroutineName = void function(GLuint, GLenum, GLuint, GLsizei, GLsizei*, GLchar*);
203         alias pglUniformSubroutinesuiv = void function(GLenum, GLsizei, const(GLuint)*);
204         alias pglGetUniformSubroutineuiv = void function(GLenum, GLint, GLuint*);
205         alias pglGetProgramStageiv = void function(GLuint, GLenum, GLenum, GLint*);
206     }
207 
208     __gshared {
209         pglGetSubroutineUniformLocation glGetSubroutineUniformLocation;
210         pglGetSubroutineIndex glGetSubroutineIndex;
211         pglGetActiveSubroutineUniformiv glGetActiveSubroutineUniformiv;
212         pglGetActiveSubroutineUniformName glGetActiveSubroutineUniformName;
213         pglGetActiveSubroutineName glGetActiveSubroutineName;
214         pglUniformSubroutinesuiv glUniformSubroutinesuiv;
215         pglGetUniformSubroutineuiv glGetUniformSubroutineuiv;
216         pglGetProgramStageiv glGetProgramStageiv;
217     }
218 
219     private @nogc nothrow
220     bool loadARBShaderSubroutine(SharedLib lib, GLSupport contextVersion)
221     {
222         lib.bindGLSymbol(cast(void**)&glGetSubroutineUniformLocation, "glGetSubroutineUniformLocation");
223         lib.bindGLSymbol(cast(void**)&glGetSubroutineIndex, "glGetSubroutineIndex");
224         lib.bindGLSymbol(cast(void**)&glGetActiveSubroutineUniformiv, "glGetActiveSubroutineUniformiv");
225         lib.bindGLSymbol(cast(void**)&glGetActiveSubroutineUniformName, "glGetActiveSubroutineUniformName");
226         lib.bindGLSymbol(cast(void**)&glGetActiveSubroutineName, "glGetActiveSubroutineName");
227         lib.bindGLSymbol(cast(void**)&glUniformSubroutinesuiv, "glUniformSubroutinesuiv");
228         lib.bindGLSymbol(cast(void**)&glGetUniformSubroutineuiv, "glGetUniformSubroutineuiv");
229         lib.bindGLSymbol(cast(void**)&glGetProgramStageiv, "glGetProgramStageiv");
230         return resetErrorCountGL();
231     }
232 }
233 else enum hasARBShaderSubroutine = false;
234 
235 // ARB_tessellation_shader
236 version(GL_ARB) enum useARBTesselationShader = true;
237 else version(GL_ARB_tessellation_shader) enum useARBTesselationShader = true;
238 else enum useARBTesselationShader = has40;
239 
240 static if(useARBTesselationShader) {
241     private bool _hasARBTesselationShader;
242     @nogc nothrow bool hasARBTesselationShader() { return _hasARBTesselationShader; }
243 
244     enum : uint {
245         GL_PATCHES                        = 0x000E,
246         GL_PATCH_VERTICES                 = 0x8E72,
247         GL_PATCH_DEFAULT_INNER_LEVEL      = 0x8E73,
248         GL_PATCH_DEFAULT_OUTER_LEVEL      = 0x8E74,
249         GL_TESS_CONTROL_OUTPUT_VERTICES   = 0x8E75,
250         GL_TESS_GEN_MODE                  = 0x8E76,
251         GL_TESS_GEN_SPACING               = 0x8E77,
252         GL_TESS_GEN_VERTEX_ORDER          = 0x8E78,
253         GL_TESS_GEN_POINT_MODE            = 0x8E79,
254         GL_ISOLINES                       = 0x8E7A,
255         GL_FRACTIONAL_ODD                 = 0x8E7B,
256         GL_FRACTIONAL_EVEN                = 0x8E7C,
257         GL_MAX_PATCH_VERTICES             = 0x8E7D,
258         GL_MAX_TESS_GEN_LEVEL             = 0x8E7E,
259         GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E7F,
260         GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E80,
261         GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS = 0x8E81,
262         GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS = 0x8E82,
263         GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS = 0x8E83,
264         GL_MAX_TESS_PATCH_COMPONENTS      = 0x8E84,
265         GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS = 0x8E85,
266         GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS = 0x8E86,
267         GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS = 0x8E89,
268         GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS = 0x8E8A,
269         GL_MAX_TESS_CONTROL_INPUT_COMPONENTS = 0x886C,
270         GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS = 0x886D,
271         GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS = 0x8E1E,
272         GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS = 0x8E1F,
273         GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = 0x84F0,
274         GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x84F1,
275         GL_TESS_EVALUATION_SHADER         = 0x8E87,
276         GL_TESS_CONTROL_SHADER            = 0x8E88,
277     }
278 
279     extern(System) @nogc nothrow {
280         alias pglPatchParameteri = void function(GLenum, GLint);
281         alias pglPatchParameterfv = void function(GLenum, const(GLfloat)*);
282     }
283 
284     __gshared {
285         pglPatchParameteri glPatchParameteri;
286         pglPatchParameterfv glPatchParameterfv;
287     }
288 
289     private @nogc nothrow
290     bool loadARBTesselationShader(SharedLib lib, GLSupport contextVersion)
291     {
292         lib.bindGLSymbol(cast(void**)&glPatchParameteri, "glPatchParameteri");
293         lib.bindGLSymbol(cast(void**)&glPatchParameterfv, "glPatchParameterfv");
294         return resetErrorCountGL();
295     }
296 }
297 else enum hasARBTesselationShader = false;
298 
299 // ARB_transform_feedback2
300 version(GL_ARB) enum useARBTransformFeedback2 = true;
301 else version(GL_ARB_transform_feedback2) enum useARBTransformFeedback2 = true;
302 else enum useARBTransformFeedback2 = has40;
303 
304 static if(useARBTransformFeedback2) {
305     private bool _hasARBTransformFeedback2;
306     @nogc nothrow bool hasARBTransformFeedback2() { return _hasARBTransformFeedback2; }
307 
308     enum : uint {
309         GL_TRANSFORM_FEEDBACK             = 0x8E22,
310         GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED = 0x8E23,
311         GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE = 0x8E24,
312         GL_TRANSFORM_FEEDBACK_BINDING     = 0x8E25,
313     }
314 
315     extern(System) @nogc nothrow {
316         alias pglBindTransformFeedback = void function(GLenum, GLuint);
317         alias pglDeleteTransformFeedbacks = void function(GLsizei, const(GLuint)*);
318         alias pglGenTransformFeedbacks = void function(GLsizei, GLuint*);
319         alias pglIsTransformFeedback = GLboolean function(GLuint);
320         alias pglPauseTransformFeedback = void function();
321         alias pglResumeTransformFeedback = void function();
322         alias pglDrawTransformFeedback = void function(GLenum, GLuint);
323     }
324 
325     __gshared {
326         pglBindTransformFeedback glBindTransformFeedback;
327         pglDeleteTransformFeedbacks glDeleteTransformFeedbacks;
328         pglGenTransformFeedbacks glGenTransformFeedbacks;
329         pglIsTransformFeedback glIsTransformFeedback;
330         pglPauseTransformFeedback glPauseTransformFeedback;
331         pglResumeTransformFeedback glResumeTransformFeedback;
332         pglDrawTransformFeedback glDrawTransformFeedback;
333     }
334 
335     private @nogc nothrow
336     bool loadARBTransformFeedback2(SharedLib lib, GLSupport contextVersion)
337     {
338         lib.bindGLSymbol(cast(void**)&glBindTransformFeedback, "glBindTransformFeedback");
339         lib.bindGLSymbol(cast(void**)&glDeleteTransformFeedbacks, "glDeleteTransformFeedbacks");
340         lib.bindGLSymbol(cast(void**)&glGenTransformFeedbacks, "glGenTransformFeedbacks");
341         lib.bindGLSymbol(cast(void**)&glIsTransformFeedback, "glIsTransformFeedback");
342         lib.bindGLSymbol(cast(void**)&glPauseTransformFeedback, "glPauseTransformFeedback");
343         lib.bindGLSymbol(cast(void**)&glResumeTransformFeedback, "glResumeTransformFeedback");
344         lib.bindGLSymbol(cast(void**)&glDrawTransformFeedback, "glDrawTransformFeedback");
345         return resetErrorCountGL();
346     }
347 }
348 else enum hasARBTransformFeedback2 = false;
349 
350 // ARB_transform_feedback3
351 version(GL_ARB) enum useARBTransformFeedback3 = true;
352 else version(GL_ARB_transform_feedback3) enum useARBTransformFeedback3 = true;
353 else enum useARBTransformFeedback3 = has40;
354 
355 static if(useARBTransformFeedback3) {
356     private bool _hasARBTransformFeedback3;
357     @nogc nothrow bool hasARBTransformFeedback3() { return _hasARBTransformFeedback3; }
358 
359     enum : uint {
360         GL_MAX_TRANSFORM_FEEDBACK_BUFFERS = 0x8E70,
361         GL_MAX_VERTEX_STREAMS             = 0x8E71,
362     }
363 
364     extern(System) @nogc nothrow {
365         alias pglDrawTransformFeedbackStream = void function(GLenum, GLuint, GLuint);
366         alias pglBeginQueryIndexed = void function(GLenum, GLuint, GLuint);
367         alias pglEndQueryIndexed = void function(GLenum, GLuint);
368         alias pglGetQueryIndexediv = void function(GLenum, GLuint, GLenum, GLint*);
369     }
370 
371     __gshared {
372         pglDrawTransformFeedbackStream glDrawTransformFeedbackStream;
373         pglBeginQueryIndexed glBeginQueryIndexed;
374         pglEndQueryIndexed glEndQueryIndexed;
375         pglGetQueryIndexediv glGetQueryIndexediv;
376     }
377 
378     private @nogc nothrow
379     bool loadARBTransformFeedback3(SharedLib lib, GLSupport contextVersion)
380     {
381         lib.bindGLSymbol(cast(void**)&glDrawTransformFeedbackStream, "glDrawTransformFeedbackStream");
382         lib.bindGLSymbol(cast(void**)&glBeginQueryIndexed, "glBeginQueryIndexed");
383         lib.bindGLSymbol(cast(void**)&glEndQueryIndexed, "glEndQueryIndexed");
384         lib.bindGLSymbol(cast(void**)&glGetQueryIndexediv, "glGetQueryIndexediv");
385         return resetErrorCountGL();
386     }
387 }
388 else enum hasARBTransformFeedback3 = false;
389 
390 package(bindbc.opengl) @nogc nothrow
391 bool loadARB40(SharedLib lib, GLSupport contextVersion)
392 {
393     static if(has40) {
394         if(contextVersion >= GLSupport.gl40) {
395             _hasARBGPUShader5 = true;
396 
397             bool ret = true;
398             ret = _hasARBDrawIndirect = lib.loadARBDrawIndirect(contextVersion);
399             ret = _hasARBGPUShaderFP64 = lib.loadARBGPUShaderFP64(contextVersion);
400             ret = _hasARBShaderSubroutine = lib.loadARBShaderSubroutine(contextVersion);
401             ret = _hasARBTesselationShader = lib.loadARBTesselationShader(contextVersion);
402             ret = _hasARBTransformFeedback2 = lib.loadARBTransformFeedback2(contextVersion);
403             ret = _hasARBTransformFeedback3 = lib.loadARBTransformFeedback3(contextVersion);
404             return ret;
405         }
406     }
407 
408     static if(useARBGPUShader5) _hasARBGPUShader5 =
409             hasExtension(contextVersion, "GL_ARB_gpu_shader5");
410 
411     static if(useARBDrawIndirect) _hasARBDrawIndirect =
412             hasExtension(contextVersion, "GL_ARB_draw_indirect") &&
413             lib.loadARBDrawIndirect(contextVersion);
414 
415     static if(useARBGPUShaderFP64) _hasARBGPUShaderFP64 =
416             hasExtension(contextVersion, "GL_ARB_gpu_shader_fp64") &&
417             lib.loadARBGPUShaderFP64(contextVersion);
418 
419     static if(useARBShaderSubroutine) _hasARBShaderSubroutine =
420             hasExtension(contextVersion, "GL_ARB_shader_subroutine") &&
421             lib.loadARBShaderSubroutine(contextVersion);
422 
423     static if(useARBTesselationShader) _hasARBTesselationShader =
424             hasExtension(contextVersion, "GL_ARB_tessellation_shader") &&
425             lib.loadARBTesselationShader(contextVersion);
426 
427     static if(useARBTransformFeedback2) _hasARBTransformFeedback2 =
428             hasExtension(contextVersion, "GL_ARB_transform_feedback2") &&
429             lib.loadARBTransformFeedback2(contextVersion);
430 
431     static if(useARBTransformFeedback3) _hasARBTransformFeedback3 =
432             hasExtension(contextVersion, "GL_ARB_transform_feedback3") &&
433             lib.loadARBTransformFeedback3(contextVersion);
434 
435     return true;
436 }