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_41;
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.gl41) {
15     enum has41 = true;
16 }
17 else enum has41 = false;
18 
19 // ARB_ES2_compatibility
20 version(GL_ARB) enum useARBES2Compatibility = true;
21 else version(GL_ARB_ES2_compatibility) enum useARBES2Compatibility = true;
22 else enum useARBES2Compatibility = has41;
23 
24 static if(useARBES2Compatibility) {
25     private bool _hasARBES2Compatibility;
26     @nogc nothrow bool hasARBES2Compatibility() { return _hasARBES2Compatibility; }
27 
28     enum : uint {
29         GL_FIXED                          = 0x140C,
30         GL_IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A,
31         GL_IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B,
32         GL_LOW_FLOAT                      = 0x8DF0,
33         GL_MEDIUM_FLOAT                   = 0x8DF1,
34         GL_HIGH_FLOAT                     = 0x8DF2,
35         GL_LOW_INT                        = 0x8DF3,
36         GL_MEDIUM_INT                     = 0x8DF4,
37         GL_HIGH_INT                       = 0x8DF5,
38         GL_SHADER_COMPILER                = 0x8DFA,
39         GL_SHADER_BINARY_FORMATS          = 0x8DF8,
40         GL_NUM_SHADER_BINARY_FORMATS      = 0x8DF9,
41         GL_MAX_VERTEX_UNIFORM_VECTORS     = 0x8DFB,
42         GL_MAX_VARYING_VECTORS            = 0x8DFC,
43         GL_MAX_FRAGMENT_UNIFORM_VECTORS   = 0x8DFD,
44         GL_RGB565                         = 0x8D62,
45     }
46 
47     extern(System) @nogc nothrow {
48         alias pglReleaseShaderCompiler = void function();
49         alias pglShaderBinary = void function(GLsizei, const(GLuint)*, GLenum, const(GLvoid)*, GLsizei);
50         alias pglGetShaderPrecisionFormat = void function(GLenum, GLenum, GLint*, GLint*);
51         alias pglDepthRangef = void function(GLclampf, GLclampf);
52         alias pglClearDepthf = void function(GLclampf);
53     }
54 
55     __gshared {
56         pglReleaseShaderCompiler glReleaseShaderCompiler;
57         pglShaderBinary glShaderBinary;
58         pglGetShaderPrecisionFormat glGetShaderPrecisionFormat;
59         pglDepthRangef glDepthRangef;
60         pglClearDepthf glClearDepthf;
61     }
62 
63     private @nogc nothrow
64     bool loadARBES2Compatibility(SharedLib lib, GLSupport contextVersion)
65     {
66         lib.bindGLSymbol(cast(void**)&glReleaseShaderCompiler, "glReleaseShaderCompiler");
67         lib.bindGLSymbol(cast(void**)&glShaderBinary, "glShaderBinary");
68         lib.bindGLSymbol(cast(void**)&glGetShaderPrecisionFormat, "glGetShaderPrecisionFormat");
69         lib.bindGLSymbol(cast(void**)&glDepthRangef, "glDepthRangef");
70         lib.bindGLSymbol(cast(void**)&glClearDepthf, "glClearDepthf");
71         return resetErrorCountGL();
72     }
73 }
74 else enum hasARBES2Compatibility = false;
75 
76 // ARB_get_program_binary
77 version(GL_ARB) enum useARBGetProgramBinary = true;
78 else version(GL_ARB_get_program_binary) enum useARBGetProgramBinary = true;
79 else enum useARBGetProgramBinary = has41;
80 
81 static if(useARBGetProgramBinary) {
82     private bool _hasARBGetProgramBinary;
83     @nogc nothrow bool hasARBGetProgramBinary() { return _hasARBGetProgramBinary; }
84 
85     enum : uint {
86         GL_PROGRAM_BINARY_RETRIEVABLE_HINT = 0x8257,
87         GL_PROGRAM_BINARY_LENGTH          = 0x8741,
88         GL_NUM_PROGRAM_BINARY_FORMATS     = 0x87FE,
89         GL_PROGRAM_BINARY_FORMATS         = 0x87FF,
90     }
91 
92     extern(System) @nogc nothrow {
93         alias pglGetProgramBinary = void function(GLuint,GLsizei,GLsizei*,GLenum*,GLvoid*);
94         alias pglProgramBinary = void function(GLuint,GLenum,const(GLvoid)*,GLsizei);
95         alias pglProgramParameteri = void function(GLuint,GLenum,GLint);
96     }
97 
98     __gshared {
99         pglGetProgramBinary glGetProgramBinary;
100         pglProgramBinary glProgramBinary;
101         pglProgramParameteri glProgramParameteri;
102     }
103 
104     private @nogc nothrow
105     bool loadARBGetProgramBinary(SharedLib lib, GLSupport contextVersion)
106     {
107         lib.bindGLSymbol(cast(void**)&glGetProgramBinary,"glGetProgramBinary");
108         lib.bindGLSymbol(cast(void**)&glProgramBinary,"glProgramBinary");
109         lib.bindGLSymbol(cast(void**)&glProgramParameteri,"glProgramParameteri");
110         return resetErrorCountGL();
111     }
112 }
113 else enum hasARBGetProgramBinary = false;
114 
115 // ARB_separate_shader_objects
116 version(GL_ARB) enum useARBSeparateShaderObjects = true;
117 else version(GL_ARB_separate_shader_objects) enum useARBSeparateShaderObjects = true;
118 else enum useARBSeparateShaderObjects = has41;
119 
120 static if(useARBSeparateShaderObjects) {
121     private bool _hasARBSeparateShaderObjects;
122     @nogc nothrow bool hasARBSeparateShaderObjects() { return _hasARBSeparateShaderObjects; }
123 
124     enum : uint {
125         GL_VERTEX_SHADER_BIT              = 0x00000001,
126         GL_FRAGMENT_SHADER_BIT            = 0x00000002,
127         GL_GEOMETRY_SHADER_BIT            = 0x00000004,
128         GL_TESS_CONTROL_SHADER_BIT        = 0x00000008,
129         GL_TESS_EVALUATION_SHADER_BIT     = 0x00000010,
130         GL_ALL_SHADER_BITS                = 0xFFFFFFFF,
131         GL_PROGRAM_SEPARABLE              = 0x8258,
132         GL_ACTIVE_PROGRAM                 = 0x8259,
133         GL_PROGRAM_PIPELINE_BINDING       = 0x825A,
134     }
135 
136     extern(System) @nogc nothrow {
137         alias pglUseProgramStages = void function(GLuint, GLbitfield, GLuint);
138         alias pglActiveShaderProgram = void function(GLuint, GLuint);
139         alias pglCreateShaderProgramv = GLuint function(GLenum, GLsizei, const(GLchar*)*);
140         alias pglBindProgramPipeline = void function(GLuint);
141         alias pglDeleteProgramPipelines = void function(GLsizei, const(GLuint)*);
142         alias pglGenProgramPipelines = void function(GLsizei, GLuint*);
143         alias pglIsProgramPipeline = GLboolean function(GLuint);
144         alias pglGetProgramPipelineiv = void function(GLuint, GLenum, GLint*);
145         alias pglProgramUniform1i = void function(GLuint, GLint, GLint);
146         alias pglProgramUniform1iv = void function(GLuint, GLint, GLsizei, const(GLint)*);
147         alias pglProgramUniform1f = void function(GLuint, GLint, GLfloat);
148         alias pglProgramUniform1fv = void function(GLuint, GLint, GLsizei, const(GLfloat)*);
149         alias pglProgramUniform1d = void function(GLuint, GLint, GLdouble);
150         alias pglProgramUniform1dv = void function(GLuint, GLint, GLsizei, const(GLdouble)*);
151         alias pglProgramUniform1ui = void function(GLuint, GLint, GLuint);
152         alias pglProgramUniform1uiv = void function(GLuint, GLint, GLsizei, const(GLuint)*);
153         alias pglProgramUniform2i = void function(GLuint, GLint, GLint, GLint);
154         alias pglProgramUniform2iv = void function(GLuint, GLint, GLsizei, const(GLint)*);
155         alias pglProgramUniform2f = void function(GLuint, GLint, GLfloat, GLfloat);
156         alias pglProgramUniform2fv = void function(GLuint, GLint, GLsizei, const(GLfloat)*);
157         alias pglProgramUniform2d = void function(GLuint, GLint, GLdouble, GLdouble);
158         alias pglProgramUniform2dv = void function(GLuint, GLint, GLsizei, const(GLdouble)*);
159         alias pglProgramUniform2ui = void function(GLuint, GLint, GLuint, GLuint);
160         alias pglProgramUniform2uiv = void function(GLuint, GLint, GLsizei, const(GLuint)*);
161         alias pglProgramUniform3i = void function(GLuint, GLint, GLint, GLint, GLint);
162         alias pglProgramUniform3iv = void function(GLuint, GLint, GLsizei, const(GLint)*);
163         alias pglProgramUniform3f = void function(GLuint, GLint, GLfloat, GLfloat, GLfloat);
164         alias pglProgramUniform3fv = void function(GLuint, GLint, GLsizei, const(GLfloat)*);
165         alias pglProgramUniform3d = void function(GLuint, GLint, GLdouble, GLdouble, GLdouble);
166         alias pglProgramUniform3dv = void function(GLuint, GLint, GLsizei, const(GLdouble)*);
167         alias pglProgramUniform3ui = void function(GLuint, GLint, GLuint, GLuint, GLuint);
168         alias pglProgramUniform3uiv = void function(GLuint, GLint, GLsizei, const(GLuint)*);
169         alias pglProgramUniform4i = void function(GLuint, GLint, GLint, GLint, GLint, GLint);
170         alias pglProgramUniform4iv = void function(GLuint, GLint, GLsizei, const(GLint)*);
171         alias pglProgramUniform4f = void function(GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat);
172         alias pglProgramUniform4fv = void function(GLuint, GLint, GLsizei, const(GLfloat)*);
173         alias pglProgramUniform4d = void function(GLuint, GLint, GLdouble, GLdouble, GLdouble, GLdouble);
174         alias pglProgramUniform4dv = void function(GLuint, GLint, GLsizei, const(GLdouble)*);
175         alias pglProgramUniform4ui = void function(GLuint, GLint, GLuint, GLuint, GLuint, GLuint);
176         alias pglProgramUniform4uiv = void function(GLuint, GLint, GLsizei, const(GLuint)*);
177         alias pglProgramUniformMatrix2fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
178         alias pglProgramUniformMatrix3fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
179         alias pglProgramUniformMatrix4fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
180         alias pglProgramUniformMatrix2dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
181         alias pglProgramUniformMatrix3dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
182         alias pglProgramUniformMatrix4dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
183         alias pglProgramUniformMatrix2x3fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
184         alias pglProgramUniformMatrix3x2fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
185         alias pglProgramUniformMatrix2x4fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
186         alias pglProgramUniformMatrix4x2fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
187         alias pglProgramUniformMatrix3x4fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
188         alias pglProgramUniformMatrix4x3fv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLfloat)*);
189         alias pglProgramUniformMatrix2x3dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
190         alias pglProgramUniformMatrix3x2dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
191         alias pglProgramUniformMatrix2x4dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
192         alias pglProgramUniformMatrix4x2dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
193         alias pglProgramUniformMatrix3x4dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
194         alias pglProgramUniformMatrix4x3dv = void function(GLuint, GLint, GLsizei, GLboolean, const(GLdouble)*);
195         alias pglValidateProgramPipeline = void function(GLuint);
196         alias pglGetProgramPipelineInfoLog = void function(GLuint, GLsizei, GLsizei*, GLchar*);
197     }
198 
199     __gshared {
200         pglUseProgramStages glUseProgramStages;
201         pglActiveShaderProgram glActiveShaderProgram;
202         pglCreateShaderProgramv glCreateShaderProgramv;
203         pglBindProgramPipeline glBindProgramPipeline;
204         pglDeleteProgramPipelines glDeleteProgramPipelines;
205         pglGenProgramPipelines glGenProgramPipelines;
206         pglIsProgramPipeline glIsProgramPipeline;
207         pglGetProgramPipelineiv glGetProgramPipelineiv;
208         pglProgramUniform1i glProgramUniform1i;
209         pglProgramUniform1iv glProgramUniform1iv;
210         pglProgramUniform1f glProgramUniform1f;
211         pglProgramUniform1fv glProgramUniform1fv;
212         pglProgramUniform1d glProgramUniform1d;
213         pglProgramUniform1dv glProgramUniform1dv;
214         pglProgramUniform1ui glProgramUniform1ui;
215         pglProgramUniform1uiv glProgramUniform1uiv;
216         pglProgramUniform2i glProgramUniform2i;
217         pglProgramUniform2iv glProgramUniform2iv;
218         pglProgramUniform2f glProgramUniform2f;
219         pglProgramUniform2fv glProgramUniform2fv;
220         pglProgramUniform2d glProgramUniform2d;
221         pglProgramUniform2dv glProgramUniform2dv;
222         pglProgramUniform2ui glProgramUniform2ui;
223         pglProgramUniform2uiv glProgramUniform2uiv;
224         pglProgramUniform3i glProgramUniform3i;
225         pglProgramUniform3iv glProgramUniform3iv;
226         pglProgramUniform3f glProgramUniform3f;
227         pglProgramUniform3fv glProgramUniform3fv;
228         pglProgramUniform3d glProgramUniform3d;
229         pglProgramUniform3dv glProgramUniform3dv;
230         pglProgramUniform3ui glProgramUniform3ui;
231         pglProgramUniform3uiv glProgramUniform3uiv;
232         pglProgramUniform4i glProgramUniform4i;
233         pglProgramUniform4iv glProgramUniform4iv;
234         pglProgramUniform4f glProgramUniform4f;
235         pglProgramUniform4fv glProgramUniform4fv;
236         pglProgramUniform4d glProgramUniform4d;
237         pglProgramUniform4dv glProgramUniform4dv;
238         pglProgramUniform4ui glProgramUniform4ui;
239         pglProgramUniform4uiv glProgramUniform4uiv;
240         pglProgramUniformMatrix2fv glProgramUniformMatrix2fv;
241         pglProgramUniformMatrix3fv glProgramUniformMatrix3fv;
242         pglProgramUniformMatrix4fv glProgramUniformMatrix4fv;
243         pglProgramUniformMatrix2dv glProgramUniformMatrix2dv;
244         pglProgramUniformMatrix3dv glProgramUniformMatrix3dv;
245         pglProgramUniformMatrix4dv glProgramUniformMatrix4dv;
246         pglProgramUniformMatrix2x3fv glProgramUniformMatrix2x3fv;
247         pglProgramUniformMatrix3x2fv glProgramUniformMatrix3x2fv;
248         pglProgramUniformMatrix2x4fv glProgramUniformMatrix2x4fv;
249         pglProgramUniformMatrix4x2fv glProgramUniformMatrix4x2fv;
250         pglProgramUniformMatrix3x4fv glProgramUniformMatrix3x4fv;
251         pglProgramUniformMatrix4x3fv glProgramUniformMatrix4x3fv;
252         pglProgramUniformMatrix2x3dv glProgramUniformMatrix2x3dv;
253         pglProgramUniformMatrix3x2dv glProgramUniformMatrix3x2dv;
254         pglProgramUniformMatrix2x4dv glProgramUniformMatrix2x4dv;
255         pglProgramUniformMatrix4x2dv glProgramUniformMatrix4x2dv;
256         pglProgramUniformMatrix3x4dv glProgramUniformMatrix3x4dv;
257         pglProgramUniformMatrix4x3dv glProgramUniformMatrix4x3dv;
258         pglValidateProgramPipeline glValidateProgramPipeline;
259         pglGetProgramPipelineInfoLog glGetProgramPipelineInfoLog;
260     }
261 
262     private @nogc nothrow
263     bool loadARBSeparateShaderObjects(SharedLib lib, GLSupport contextVersion)
264     {
265         lib.bindGLSymbol(cast(void**)&glUseProgramStages, "glUseProgramStages");
266         lib.bindGLSymbol(cast(void**)&glActiveShaderProgram, "glActiveShaderProgram");
267         lib.bindGLSymbol(cast(void**)&glCreateShaderProgramv, "glCreateShaderProgramv");
268         lib.bindGLSymbol(cast(void**)&glBindProgramPipeline, "glBindProgramPipeline");
269         lib.bindGLSymbol(cast(void**)&glDeleteProgramPipelines, "glDeleteProgramPipelines");
270         lib.bindGLSymbol(cast(void**)&glGenProgramPipelines, "glGenProgramPipelines");
271         lib.bindGLSymbol(cast(void**)&glIsProgramPipeline, "glIsProgramPipeline");
272         lib.bindGLSymbol(cast(void**)&glGetProgramPipelineiv, "glGetProgramPipelineiv");
273         lib.bindGLSymbol(cast(void**)&glProgramUniform1i, "glProgramUniform1i");
274         lib.bindGLSymbol(cast(void**)&glProgramUniform1iv, "glProgramUniform1iv");
275         lib.bindGLSymbol(cast(void**)&glProgramUniform1f, "glProgramUniform1f");
276         lib.bindGLSymbol(cast(void**)&glProgramUniform1fv, "glProgramUniform1fv");
277         lib.bindGLSymbol(cast(void**)&glProgramUniform1d, "glProgramUniform1d");
278         lib.bindGLSymbol(cast(void**)&glProgramUniform1dv, "glProgramUniform1dv");
279         lib.bindGLSymbol(cast(void**)&glProgramUniform1ui, "glProgramUniform1ui");
280         lib.bindGLSymbol(cast(void**)&glProgramUniform1uiv, "glProgramUniform1uiv");
281         lib.bindGLSymbol(cast(void**)&glProgramUniform2i, "glProgramUniform2i");
282         lib.bindGLSymbol(cast(void**)&glProgramUniform2iv, "glProgramUniform2iv");
283         lib.bindGLSymbol(cast(void**)&glProgramUniform2f, "glProgramUniform2f");
284         lib.bindGLSymbol(cast(void**)&glProgramUniform2fv, "glProgramUniform2fv");
285         lib.bindGLSymbol(cast(void**)&glProgramUniform2d, "glProgramUniform2d");
286         lib.bindGLSymbol(cast(void**)&glProgramUniform2dv, "glProgramUniform2dv");
287         lib.bindGLSymbol(cast(void**)&glProgramUniform2ui, "glProgramUniform2ui");
288         lib.bindGLSymbol(cast(void**)&glProgramUniform2uiv, "glProgramUniform2uiv");
289         lib.bindGLSymbol(cast(void**)&glProgramUniform3i, "glProgramUniform3i");
290         lib.bindGLSymbol(cast(void**)&glProgramUniform3iv, "glProgramUniform3iv");
291         lib.bindGLSymbol(cast(void**)&glProgramUniform3f, "glProgramUniform3f");
292         lib.bindGLSymbol(cast(void**)&glProgramUniform3fv, "glProgramUniform3fv");
293         lib.bindGLSymbol(cast(void**)&glProgramUniform3d, "glProgramUniform3d");
294         lib.bindGLSymbol(cast(void**)&glProgramUniform3dv, "glProgramUniform3dv");
295         lib.bindGLSymbol(cast(void**)&glProgramUniform3ui, "glProgramUniform3ui");
296         lib.bindGLSymbol(cast(void**)&glProgramUniform3uiv, "glProgramUniform3uiv");
297         lib.bindGLSymbol(cast(void**)&glProgramUniform4i, "glProgramUniform4i");
298         lib.bindGLSymbol(cast(void**)&glProgramUniform4iv, "glProgramUniform4iv");
299         lib.bindGLSymbol(cast(void**)&glProgramUniform4f, "glProgramUniform4f");
300         lib.bindGLSymbol(cast(void**)&glProgramUniform4fv, "glProgramUniform4fv");
301         lib.bindGLSymbol(cast(void**)&glProgramUniform4d, "glProgramUniform4d");
302         lib.bindGLSymbol(cast(void**)&glProgramUniform4dv, "glProgramUniform4dv");
303         lib.bindGLSymbol(cast(void**)&glProgramUniform4ui, "glProgramUniform4ui");
304         lib.bindGLSymbol(cast(void**)&glProgramUniform4uiv, "glProgramUniform4uiv");
305         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix2fv, "glProgramUniformMatrix2fv");
306         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix3fv, "glProgramUniformMatrix3fv");
307         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix4fv, "glProgramUniformMatrix4fv");
308         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix2dv, "glProgramUniformMatrix2dv");
309         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix3dv, "glProgramUniformMatrix3dv");
310         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix4dv, "glProgramUniformMatrix4dv");
311         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix2x3fv, "glProgramUniformMatrix2x3fv");
312         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix3x2fv, "glProgramUniformMatrix3x2fv");
313         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix2x4fv, "glProgramUniformMatrix2x4fv");
314         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix4x2fv, "glProgramUniformMatrix4x2fv");
315         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix3x4fv, "glProgramUniformMatrix3x4fv");
316         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix4x3fv, "glProgramUniformMatrix4x3fv");
317         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix2x3dv, "glProgramUniformMatrix2x3dv");
318         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix3x2dv, "glProgramUniformMatrix3x2dv");
319         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix2x4dv, "glProgramUniformMatrix2x4dv");
320         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix4x2dv, "glProgramUniformMatrix4x2dv");
321         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix3x4dv, "glProgramUniformMatrix3x4dv");
322         lib.bindGLSymbol(cast(void**)&glProgramUniformMatrix4x3dv, "glProgramUniformMatrix4x3dv");
323         lib.bindGLSymbol(cast(void**)&glValidateProgramPipeline, "glValidateProgramPipeline");
324         lib.bindGLSymbol(cast(void**)&glGetProgramPipelineInfoLog, "glGetProgramPipelineInfoLog");
325         return resetErrorCountGL();
326     }
327 }
328 else enum hasARBSeparateShaderObjects = false;
329 
330 // ARB_vertex_attrib_64bit
331 version(GL_ARB) enum useARBVertexAttrib64Bit = true;
332 else version(GL_ARB_vertex_attrib_64bit) enum useARBVertexAttrib64Bit = true;
333 else enum useARBVertexAttrib64Bit = has41;
334 
335 static if(useARBVertexAttrib64Bit) {
336     private bool _hasARBVertexAttrib64Bit;
337     @nogc nothrow bool hasARBVertexAttrib64Bit() { return _hasARBVertexAttrib64Bit; }
338 
339     extern(System) @nogc nothrow {
340         alias pglVertexAttribL1d = void function(GLuint, GLdouble);
341         alias pglVertexAttribL2d = void function(GLuint, GLdouble, GLdouble);
342         alias pglVertexAttribL3d = void function(GLuint, GLdouble, GLdouble, GLdouble);
343         alias pglVertexAttribL4d = void function(GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
344         alias pglVertexAttribL1dv = void function(GLuint, const(GLdouble)*);
345         alias pglVertexAttribL2dv = void function(GLuint, const(GLdouble)*);
346         alias pglVertexAttribL3dv = void function(GLuint, const(GLdouble)*);
347         alias pglVertexAttribL4dv = void function(GLuint, const(GLdouble)*);
348         alias pglVertexAttribLPointer = void function(GLuint, GLint, GLenum, GLsizei, const(GLvoid)*);
349         alias pglGetVertexAttribLdv = void function(GLuint, GLenum, GLdouble*);
350     }
351 
352     __gshared {
353         pglVertexAttribL1d glVertexAttribL1d;
354         pglVertexAttribL2d glVertexAttribL2d;
355         pglVertexAttribL3d glVertexAttribL3d;
356         pglVertexAttribL4d glVertexAttribL4d;
357         pglVertexAttribL1dv glVertexAttribL1dv;
358         pglVertexAttribL2dv glVertexAttribL2dv;
359         pglVertexAttribL3dv glVertexAttribL3dv;
360         pglVertexAttribL4dv glVertexAttribL4dv;
361         pglVertexAttribLPointer glVertexAttribLPointer;
362         pglGetVertexAttribLdv glGetVertexAttribLdv;
363     }
364 
365     private @nogc nothrow
366     bool loadARBVertexAttrib64Bit(SharedLib lib, GLSupport contextVersion)
367     {
368         lib.bindGLSymbol(cast(void**)&glVertexAttribL1d, "glVertexAttribL1d");
369         lib.bindGLSymbol(cast(void**)&glVertexAttribL2d, "glVertexAttribL2d");
370         lib.bindGLSymbol(cast(void**)&glVertexAttribL3d, "glVertexAttribL3d");
371         lib.bindGLSymbol(cast(void**)&glVertexAttribL4d, "glVertexAttribL4d");
372         lib.bindGLSymbol(cast(void**)&glVertexAttribL1dv, "glVertexAttribL1dv");
373         lib.bindGLSymbol(cast(void**)&glVertexAttribL2dv, "glVertexAttribL2dv");
374         lib.bindGLSymbol(cast(void**)&glVertexAttribL3dv, "glVertexAttribL3dv");
375         lib.bindGLSymbol(cast(void**)&glVertexAttribL4dv, "glVertexAttribL4dv");
376         lib.bindGLSymbol(cast(void**)&glVertexAttribLPointer, "glVertexAttribLPointer");
377         lib.bindGLSymbol(cast(void**)&glGetVertexAttribLdv, "glGetVertexAttribLdv");
378         return resetErrorCountGL();
379     }
380 }
381 else enum hasARBVertexAttrib64Bit = false;
382 
383 // ARB_viewport_array
384 version(GL_ARB) enum useARBViewportArray = true;
385 else version(GL_ARB_viewport_array) enum useARBViewportArray = true;
386 else enum useARBViewportArray = has41;
387 
388 static if(useARBViewportArray) {
389     private bool _hasARBViewportArray;
390     @nogc nothrow bool hasARBViewportArray() { return _hasARBViewportArray; }
391 
392     enum : uint {
393         GL_MAX_VIEWPORTS                  = 0x825B,
394         GL_VIEWPORT_SUBPIXEL_BITS         = 0x825C,
395         GL_VIEWPORT_BOUNDS_RANGE          = 0x825D,
396         GL_LAYER_PROVOKING_VERTEX         = 0x825E,
397         GL_VIEWPORT_INDEX_PROVOKING_VERTEX = 0x825F,
398         GL_UNDEFINED_VERTEX               = 0x8260,
399     }
400 
401     extern(System) @nogc nothrow {
402         alias pglViewportArrayv = void function(GLuint, GLsizei, const(GLfloat)*);
403         alias pglViewportIndexedf = void function(GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
404         alias pglViewportIndexedfv = void function(GLuint, const(GLfloat)*);
405         alias pglScissorArrayv = void function(GLuint, GLsizei, const(GLint)*);
406         alias pglScissorIndexed = void function(GLuint, GLint, GLint, GLsizei, GLsizei);
407         alias pglScissorIndexedv = void function(GLuint, const(GLint)*);
408         alias pglDepthRangeArrayv = void function(GLuint, GLsizei, const(GLclampd)*);
409         alias pglDepthRangeIndexed = void function(GLuint, GLclampd, GLclampd);
410         alias pglGetFloati_v = void function(GLenum, GLuint, GLfloat*);
411         alias pglGetDoublei_v = void function(GLenum, GLuint, GLdouble*);
412     }
413 
414     __gshared {
415         pglViewportArrayv glViewportArrayv;
416         pglViewportIndexedf glViewportIndexedf;
417         pglViewportIndexedfv glViewportIndexedfv;
418         pglScissorArrayv glScissorArrayv;
419         pglScissorIndexed glScissorIndexed;
420         pglScissorIndexedv glScissorIndexedv;
421         pglDepthRangeArrayv glDepthRangeArrayv;
422         pglDepthRangeIndexed glDepthRangeIndexed;
423         pglGetFloati_v glGetFloati_v;
424         pglGetDoublei_v glGetDoublei_v;
425     }
426 
427     private @nogc nothrow
428     bool loadARBViewportArray(SharedLib lib, GLSupport contextVersion)
429     {
430         lib.bindGLSymbol(cast(void**)&glViewportArrayv, "glViewportArrayv");
431         lib.bindGLSymbol(cast(void**)&glViewportIndexedf, "glViewportIndexedf");
432         lib.bindGLSymbol(cast(void**)&glViewportIndexedfv, "glViewportIndexedfv");
433         lib.bindGLSymbol(cast(void**)&glScissorArrayv, "glScissorArrayv");
434         lib.bindGLSymbol(cast(void**)&glScissorIndexed, "glScissorIndexed");
435         lib.bindGLSymbol(cast(void**)&glScissorIndexedv, "glScissorIndexedv");
436         lib.bindGLSymbol(cast(void**)&glDepthRangeArrayv, "glDepthRangeArrayv");
437         lib.bindGLSymbol(cast(void**)&glDepthRangeIndexed, "glDepthRangeIndexed");
438         lib.bindGLSymbol(cast(void**)&glGetFloati_v, "glGetFloati_v");
439         lib.bindGLSymbol(cast(void**)&glGetDoublei_v, "glGetDoublei_v");
440         return resetErrorCountGL();
441     }
442 }
443 else enum hasARBViewportArray = false;
444 
445 package(bindbc.opengl) @nogc nothrow
446 bool loadARB41(SharedLib lib, GLSupport contextVersion)
447 {
448     static if(has41) {
449         if(contextVersion >= GLSupport.gl41) {
450             bool ret = true;
451             ret = _hasARBES2Compatibility = lib.loadARBES2Compatibility(contextVersion);
452             ret = _hasARBGetProgramBinary = lib.loadARBGetProgramBinary(contextVersion);
453             ret = _hasARBSeparateShaderObjects = lib.loadARBSeparateShaderObjects(contextVersion);
454             ret = _hasARBVertexAttrib64Bit = lib.loadARBVertexAttrib64Bit(contextVersion);
455             ret = _hasARBViewportArray = lib.loadARBViewportArray(contextVersion);
456             return ret;
457         }
458     }
459 
460     static if(useARBES2Compatibility) _hasARBES2Compatibility =
461             hasExtension(contextVersion, "GL_ARB_ES2_compatibility") &&
462             lib.loadARBES2Compatibility(contextVersion);
463 
464     static if(useARBGetProgramBinary) _hasARBGetProgramBinary =
465             hasExtension(contextVersion, "GL_ARB_get_program_binary") &&
466             lib.loadARBGetProgramBinary(contextVersion);
467 
468     static if(useARBSeparateShaderObjects) _hasARBSeparateShaderObjects =
469             hasExtension(contextVersion, "GL_ARB_separate_shader_objects") &&
470             lib.loadARBSeparateShaderObjects(contextVersion);
471 
472     static if(useARBVertexAttrib64Bit) _hasARBVertexAttrib64Bit =
473             hasExtension(contextVersion, "GL_ARB_vertex_attrib_64bit") &&
474             lib.loadARBVertexAttrib64Bit(contextVersion);
475 
476     static if(useARBViewportArray) _hasARBViewportArray =
477             hasExtension(contextVersion, "GL_ARB_viewport_array") &&
478             lib.loadARBViewportArray(contextVersion);
479 
480     return true;
481 }