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_42;
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.gl42) {
15     enum has42 = true;
16 }
17 else enum has42 = false;
18 
19 // ARB_base_instance
20 version(GL_ARB) enum useARBBaseInstance = true;
21 else version(GL_ARB_base_instance) enum useARBBaseInstance = true;
22 else enum useARBBaseInstance = has42;
23 
24 static if(useARBBaseInstance) {
25     private bool _hasARBBaseInstance;
26     @nogc nothrow bool hasARBBaseInstance() { return _hasARBBaseInstance; }
27 
28     extern(System) @nogc nothrow  {
29         alias pglDrawArraysInstancedBaseInstance = void function(GLenum, GLint, GLsizei, GLsizei, GLuint);
30         alias pglDrawElementsInstancedBaseInstance = void function(GLenum, GLsizei, GLenum, const(void)*, GLsizei, GLuint);
31         alias pglDrawElementsInstancedBaseVertexBaseInstance = void function(GLenum, GLsizei, GLenum, const(void)*, GLsizei, GLint, GLuint);
32     }
33 
34     __gshared {
35         pglDrawArraysInstancedBaseInstance glDrawArraysInstancedBaseInstance;
36         pglDrawElementsInstancedBaseInstance glDrawElementsInstancedBaseInstance;
37         pglDrawElementsInstancedBaseVertexBaseInstance glDrawElementsInstancedBaseVertexBaseInstance;
38     }
39 
40     private @nogc nothrow
41     bool loadARBBaseInstance(SharedLib lib, GLSupport contextVersion)
42     {
43         lib.bindGLSymbol(cast(void**)&glDrawArraysInstancedBaseInstance, "glDrawArraysInstancedBaseInstance");
44         lib.bindGLSymbol(cast(void**)&glDrawElementsInstancedBaseInstance, "glDrawElementsInstancedBaseInstance");
45         lib.bindGLSymbol(cast(void**)&glDrawElementsInstancedBaseVertexBaseInstance, "glDrawElementsInstancedBaseVertexBaseInstance");
46         return resetErrorCountGL();
47     }
48 }
49 else enum hasARBBaseInstance = false;
50 
51 // ARB_compressed_texture_pixel_storage
52 version(GL_ARB) enum useARBCompressedTexturePixelStorage = true;
53 else version(GL_ARB_compressed_texture_pixel_storage) enum useARBCompressedTexturePixelStorage = true;
54 else enum useARBCompressedTexturePixelStorage = has42;
55 
56 static if(useARBCompressedTexturePixelStorage) {
57     private bool _hasARBCompressedTexturePixelStorage;
58     @nogc nothrow bool hasARBCompressedTexturePixelStorage() { return _hasARBCompressedTexturePixelStorage; }
59 
60     enum : uint {
61         GL_UNPACK_COMPRESSED_BLOCK_WIDTH  = 0x9127,
62         GL_UNPACK_COMPRESSED_BLOCK_HEIGHT = 0x9128,
63         GL_UNPACK_COMPRESSED_BLOCK_DEPTH  = 0x9129,
64         GL_UNPACK_COMPRESSED_BLOCK_SIZE   = 0x912A,
65         GL_PACK_COMPRESSED_BLOCK_WIDTH    = 0x912B,
66         GL_PACK_COMPRESSED_BLOCK_HEIGHT   = 0x912C,
67         GL_PACK_COMPRESSED_BLOCK_DEPTH    = 0x912D,
68         GL_PACK_COMPRESSED_BLOCK_SIZE     = 0x912E,
69     }
70 }
71 else enum hasARBCompressedTexturePixelStorage = false;
72 
73 // ARB_internalformat_query
74 version(GL_ARB) enum useARBInternalFormatQuery = true;
75 else version(GL_ARB_internalformat_query) enum useARBInternalFormatQuery = true;
76 else enum useARBInternalFormatQuery = has42;
77 
78 static if(useARBInternalFormatQuery) {
79     private bool _hasARBInternalFormatQuery;
80     @nogc nothrow bool hasARBInternalFormatQuery() { return _hasARBInternalFormatQuery; }
81 
82     enum uint GL_NUM_SAMPLE_COUNTS = 0x9380;
83     extern(System) @nogc nothrow alias pglGetInternalformativ = void function(GLenum, GLenum, GLenum, GLsizei, GLint*);
84     __gshared pglGetInternalformativ glGetInternalformativ;
85 
86     private @nogc nothrow
87     bool loadARBInternalFormatQuery(SharedLib lib, GLSupport contextVersion)
88     {
89         lib.bindGLSymbol(cast(void**)&glGetInternalformativ, "glGetInternalformativ");
90         return resetErrorCountGL();
91     }
92 }
93 else enum hasARBInternalFormatQuery = false;
94 
95 // ARB_map_buffer_alignment
96 version(GL_ARB) enum useARBMapBufferAlignment = true;
97 else version(GL_ARB_map_buffer_alignment) enum useARBMapBufferAlignment = true;
98 else enum useARBMapBufferAlignment = has42;
99 
100 static if(useARBMapBufferAlignment) {
101     private bool _hasARBMapBufferAlignment;
102     @nogc nothrow bool hasARBMapBufferAlignment() { return _hasARBMapBufferAlignment; }
103 
104     enum uint GL_MIN_MAP_BUFFER_ALIGNMENT = 0x90BC;
105 }
106 else enum hasARBMapBufferAlignment = false;
107 
108 // ARB_shader_atomic_counters
109 version(GL_ARB) enum useARBShaderAtomicCounters = true;
110 else version(GL_ARB_shader_atomic_counters) enum useARBShaderAtomicCounters = true;
111 else enum useARBShaderAtomicCounters = has42;
112 
113 static if(useARBShaderAtomicCounters) {
114     private bool _hasARBShaderAtomicCounters;
115     @nogc nothrow bool hasARBShaderAtomicCounters() { return _hasARBShaderAtomicCounters; }
116 
117     enum : uint {
118         GL_ATOMIC_COUNTER_BUFFER          = 0x92C0,
119         GL_ATOMIC_COUNTER_BUFFER_BINDING  = 0x92C1,
120         GL_ATOMIC_COUNTER_BUFFER_START    = 0x92C2,
121         GL_ATOMIC_COUNTER_BUFFER_SIZE     = 0x92C3,
122         GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE = 0x92C4,
123         GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS = 0x92C5,
124         GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES = 0x92C6,
125         GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER = 0x92C7,
126         GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER = 0x92C8,
127         GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER = 0x92C9,
128         GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER = 0x92CA,
129         GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER = 0x92CB,
130         GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS = 0x92CC,
131         GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS = 0x92CD,
132         GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS = 0x92CE,
133         GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS = 0x92CF,
134         GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS = 0x92D0,
135         GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS = 0x92D1,
136         GL_MAX_VERTEX_ATOMIC_COUNTERS     = 0x92D2,
137         GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS = 0x92D3,
138         GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS = 0x92D4,
139         GL_MAX_GEOMETRY_ATOMIC_COUNTERS   = 0x92D5,
140         GL_MAX_FRAGMENT_ATOMIC_COUNTERS   = 0x92D6,
141         GL_MAX_COMBINED_ATOMIC_COUNTERS   = 0x92D7,
142         GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE = 0x92D8,
143         GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 0x92DC,
144         GL_ACTIVE_ATOMIC_COUNTER_BUFFERS  = 0x92D9,
145         GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX = 0x92DA,
146         GL_UNSIGNED_INT_ATOMIC_COUNTER    = 0x92DB,
147     }
148 
149     extern(System) @nogc nothrow alias pglGetActiveAtomicCounterBufferiv = void function(GLuint, GLuint, GLenum, GLint*);
150     __gshared pglGetActiveAtomicCounterBufferiv glGetActiveAtomicCounterBufferiv;
151 
152     private @nogc nothrow
153     bool loadARBShaderAtomicCounters(SharedLib lib, GLSupport contextVersion)
154     {
155         lib.bindGLSymbol(cast(void**)&glGetActiveAtomicCounterBufferiv, "glGetActiveAtomicCounterBufferiv");
156         return resetErrorCountGL();
157     }
158 }
159 else enum hasARBShaderAtomicCounters = false;
160 
161 // ARB_shader_image_load_store
162 version(GL_ARB) enum useARBShaderImageLoadStore = true;
163 else version(GL_ARB_shader_image_load_store) enum useARBShaderImageLoadStore = true;
164 else enum useARBShaderImageLoadStore = has42;
165 
166 static if(useARBShaderImageLoadStore) {
167     private bool _hasARBShaderImageLoadStore;
168     @nogc nothrow bool hasARBShaderImageLoadStore() { return _hasARBShaderImageLoadStore; }
169 
170     enum : uint {
171         GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT = 0x00000001,
172         GL_ELEMENT_ARRAY_BARRIER_BIT      = 0x00000002,
173         GL_UNIFORM_BARRIER_BIT            = 0x00000004,
174         GL_TEXTURE_FETCH_BARRIER_BIT      = 0x00000008,
175         GL_SHADER_IMAGE_ACCESS_BARRIER_BIT = 0x00000020,
176         GL_COMMAND_BARRIER_BIT            = 0x00000040,
177         GL_PIXEL_BUFFER_BARRIER_BIT       = 0x00000080,
178         GL_TEXTURE_UPDATE_BARRIER_BIT     = 0x00000100,
179         GL_BUFFER_UPDATE_BARRIER_BIT      = 0x00000200,
180         GL_FRAMEBUFFER_BARRIER_BIT        = 0x00000400,
181         GL_TRANSFORM_FEEDBACK_BARRIER_BIT = 0x00000800,
182         GL_ATOMIC_COUNTER_BARRIER_BIT     = 0x00001000,
183         GL_ALL_BARRIER_BITS               = 0xFFFFFFFF,
184         GL_MAX_IMAGE_UNITS                = 0x8F38,
185         GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS = 0x8F39,
186         GL_IMAGE_BINDING_NAME             = 0x8F3A,
187         GL_IMAGE_BINDING_LEVEL            = 0x8F3B,
188         GL_IMAGE_BINDING_LAYERED          = 0x8F3C,
189         GL_IMAGE_BINDING_LAYER            = 0x8F3D,
190         GL_IMAGE_BINDING_ACCESS           = 0x8F3E,
191         GL_IMAGE_1D                       = 0x904C,
192         GL_IMAGE_2D                       = 0x904D,
193         GL_IMAGE_3D                       = 0x904E,
194         GL_IMAGE_2D_RECT                  = 0x904F,
195         GL_IMAGE_CUBE                     = 0x9050,
196         GL_IMAGE_BUFFER                   = 0x9051,
197         GL_IMAGE_1D_ARRAY                 = 0x9052,
198         GL_IMAGE_2D_ARRAY                 = 0x9053,
199         GL_IMAGE_CUBE_MAP_ARRAY           = 0x9054,
200         GL_IMAGE_2D_MULTISAMPLE           = 0x9055,
201         GL_IMAGE_2D_MULTISAMPLE_ARRAY     = 0x9056,
202         GL_INT_IMAGE_1D                   = 0x9057,
203         GL_INT_IMAGE_2D                   = 0x9058,
204         GL_INT_IMAGE_3D                   = 0x9059,
205         GL_INT_IMAGE_2D_RECT              = 0x905A,
206         GL_INT_IMAGE_CUBE                 = 0x905B,
207         GL_INT_IMAGE_BUFFER               = 0x905C,
208         GL_INT_IMAGE_1D_ARRAY             = 0x905D,
209         GL_INT_IMAGE_2D_ARRAY             = 0x905E,
210         GL_INT_IMAGE_CUBE_MAP_ARRAY       = 0x905F,
211         GL_INT_IMAGE_2D_MULTISAMPLE       = 0x9060,
212         GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x9061,
213         GL_UNSIGNED_INT_IMAGE_1D          = 0x9062,
214         GL_UNSIGNED_INT_IMAGE_2D          = 0x9063,
215         GL_UNSIGNED_INT_IMAGE_3D          = 0x9064,
216         GL_UNSIGNED_INT_IMAGE_2D_RECT     = 0x9065,
217         GL_UNSIGNED_INT_IMAGE_CUBE        = 0x9066,
218         GL_UNSIGNED_INT_IMAGE_BUFFER      = 0x9067,
219         GL_UNSIGNED_INT_IMAGE_1D_ARRAY    = 0x9068,
220         GL_UNSIGNED_INT_IMAGE_2D_ARRAY    = 0x9069,
221         GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY = 0x906A,
222         GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE = 0x906B,
223         GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY = 0x906C,
224         GL_MAX_IMAGE_SAMPLES              = 0x906D,
225         GL_IMAGE_BINDING_FORMAT           = 0x906E,
226         GL_IMAGE_FORMAT_COMPATIBILITY_TYPE = 0x90C7,
227         GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE = 0x90C8,
228         GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS = 0x90C9,
229         GL_MAX_VERTEX_IMAGE_UNIFORMS      = 0x90CA,
230         GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS = 0x90CB,
231         GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS = 0x90CC,
232         GL_MAX_GEOMETRY_IMAGE_UNIFORMS    = 0x90CD,
233         GL_MAX_FRAGMENT_IMAGE_UNIFORMS    = 0x90CE,
234         GL_MAX_COMBINED_IMAGE_UNIFORMS    = 0x90CF,
235     }
236 
237     extern(System) @nogc nothrow  {
238         alias pglBindImageTexture = void function(GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum);
239         alias pglMemoryBarrier = void function(GLbitfield);
240     }
241 
242     __gshared {
243         pglBindImageTexture glBindImageTexture;
244         pglMemoryBarrier glMemoryBarrier;
245     }
246 
247     private @nogc nothrow
248     bool loadARBShaderImageLoadStore(SharedLib lib, GLSupport contextVersion)
249     {
250         lib.bindGLSymbol(cast(void**)&glBindImageTexture, "glBindImageTexture");
251         lib.bindGLSymbol(cast(void**)&glMemoryBarrier, "glMemoryBarrier");
252         return resetErrorCountGL();
253     }
254 }
255 else enum hasARBShaderImageLoadStore = false;
256 
257 // ARB_texture_storage
258 version(GL_ARB) enum useARBTextureStorage = true;
259 else version(GL_ARB_texture_storage) enum useARBTextureStorage = true;
260 else enum useARBTextureStorage = has42;
261 
262 static if(useARBTextureStorage) {
263     private bool _hasARBTextureStorage;
264     @nogc nothrow bool hasARBTextureStorage() { return _hasARBTextureStorage; }
265 
266     enum uint GL_TEXTURE_IMMUTABLE_FORMAT = 0x912F;
267 
268     extern(System) @nogc nothrow  {
269         alias pglTexStorage1D = void function(GLenum, GLsizei, GLenum, GLsizei);
270         alias pglTexStorage2D = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei);
271         alias pglTexStorage3D = void function(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei);
272         alias pglTextureStorage1DEXT = void function(GLuint, GLenum, GLsizei, GLenum, GLsizei);
273         alias pglTextureStorage2DEXT = void function(GLuint, GLenum, GLsizei, GLenum, GLsizei, GLsizei);
274         alias pglTextureStorage3DEXT = void function(GLuint, GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei);
275     }
276 
277     __gshared {
278         pglTexStorage1D glTexStorage1D;
279         pglTexStorage2D glTexStorage2D;
280         pglTexStorage3D glTexStorage3D;
281         pglTextureStorage1DEXT glTextureStorage1DEXT;
282         pglTextureStorage2DEXT glTextureStorage2DEXT;
283         pglTextureStorage3DEXT glTextureStorage3DEXT;
284     }
285 
286     private @nogc nothrow
287     bool loadARBTextureStorage(SharedLib lib, GLSupport contextVersion)
288     {
289         lib.bindGLSymbol(cast(void**)&glTexStorage1D, "glTexStorage1D");
290         lib.bindGLSymbol(cast(void**)&glTexStorage2D, "glTexStorage2D");
291         lib.bindGLSymbol(cast(void**)&glTexStorage3D, "glTexStorage3D");
292 
293         // The previous three functions are required when loading GL 4.2,
294         // the next three are not. Save the result of resetErrorCountGL and
295         // use that for the return value.
296         bool ret = resetErrorCountGL();
297         if(hasExtension(contextVersion, "GL_EXT_direct_state_access ")) {
298             lib.bindGLSymbol(cast(void**)&glTextureStorage1DEXT, "glTextureStorage1DEXT");
299             lib.bindGLSymbol(cast(void**)&glTextureStorage2DEXT, "glTextureStorage2DEXT");
300             lib.bindGLSymbol(cast(void**)&glTextureStorage3DEXT, "glTextureStorage3DEXT");
301 
302             // Ignore errors.
303             resetErrorCountGL();
304         }
305         return ret;
306     }
307 }
308 else enum hasARBTextureStorage = false;
309 
310 // ARB_transform_feedback_instanced
311 version(GL_ARB) enum useARBTransformFeedbackInstanced = true;
312 else version(GL_ARB_transform_feedback_instanced) enum useARBTransformFeedbackInstanced = true;
313 else enum useARBTransformFeedbackInstanced = has42;
314 
315 static if(useARBTransformFeedbackInstanced) {
316     private bool _hasARBTransformFeedbackInstanced;
317     @nogc nothrow bool hasARBTransformFeedbackInstanced() { return _hasARBTransformFeedbackInstanced; }
318 
319     extern(System) @nogc nothrow  {
320         alias pglDrawTransformFeedbackInstanced = void function(GLenum, GLuint, GLsizei);
321         alias pglDrawTransformFeedbackStreamInstanced = void function(GLenum, GLuint, GLuint, GLsizei);
322     }
323 
324     __gshared {
325         pglDrawTransformFeedbackInstanced glDrawTransformFeedbackInstanced;
326         pglDrawTransformFeedbackStreamInstanced glDrawTransformFeedbackStreamInstanced;
327     }
328 
329     private @nogc nothrow
330     bool loadARBTransformFeedbackInstanced(SharedLib lib, GLSupport contextVersion)
331     {
332         lib.bindGLSymbol(cast(void**)&glDrawTransformFeedbackInstanced, "glDrawTransformFeedbackInstanced");
333         lib.bindGLSymbol(cast(void**)&glDrawTransformFeedbackStreamInstanced, "glDrawTransformFeedbackStreamInstanced");
334         return resetErrorCountGL();
335     }
336 }
337 else enum hasARBTransformFeedbackInstanced = false;
338 
339 package(bindbc.opengl) @nogc nothrow
340 bool loadARB42(SharedLib lib, GLSupport contextVersion)
341 {
342     static if(has42) {
343         if(contextVersion >= GLSupport.gl42) {
344             _hasARBCompressedTexturePixelStorage = true;
345             _hasARBMapBufferAlignment = true;
346 
347             bool ret = true;
348             ret = _hasARBBaseInstance = lib.loadARBBaseInstance(contextVersion);
349             ret = _hasARBInternalFormatQuery = lib.loadARBInternalFormatQuery(contextVersion);
350             ret = _hasARBShaderAtomicCounters = lib.loadARBShaderAtomicCounters(contextVersion);
351             ret = _hasARBShaderImageLoadStore = lib.loadARBShaderImageLoadStore(contextVersion);
352             ret = _hasARBTextureStorage = lib.loadARBTextureStorage(contextVersion);
353             ret = _hasARBTransformFeedbackInstanced = lib.loadARBTransformFeedbackInstanced(contextVersion);
354             return ret;
355         }
356     }
357 
358     static if(useARBCompressedTexturePixelStorage) _hasARBCompressedTexturePixelStorage =
359             hasExtension(contextVersion, "GL_ARB_compressed_texture_pixel_storage");
360 
361     static if(useARBMapBufferAlignment) _hasARBMapBufferAlignment =
362             hasExtension(contextVersion, "GL_ARB_map_buffer_alignment");
363 
364     static if(useARBBaseInstance) _hasARBBaseInstance =
365             hasExtension(contextVersion, "GL_ARB_base_instance") &&
366             lib.loadARBBaseInstance(contextVersion);
367 
368     static if(useARBInternalFormatQuery) _hasARBInternalFormatQuery =
369             hasExtension(contextVersion, "GL_ARB_internalformat_query") &&
370             lib.loadARBInternalFormatQuery(contextVersion);
371 
372     static if(useARBShaderAtomicCounters) _hasARBShaderAtomicCounters =
373             hasExtension(contextVersion, "GL_ARB_shader_atomic_counters") &&
374             lib.loadARBShaderAtomicCounters(contextVersion);
375 
376     static if(useARBShaderImageLoadStore) _hasARBShaderImageLoadStore =
377             hasExtension(contextVersion, "GL_ARB_shader_image_load_store") &&
378             lib.loadARBShaderImageLoadStore(contextVersion);
379 
380     static if(useARBTextureStorage) _hasARBTextureStorage =
381             hasExtension(contextVersion, "GL_ARB_texture_storage") &&
382             lib.loadARBTextureStorage(contextVersion);
383 
384     static if(useARBTransformFeedbackInstanced) _hasARBTransformFeedbackInstanced =
385             hasExtension(contextVersion, "GL_ARB_transform_feedback_instanced") &&
386             lib.loadARBTransformFeedbackInstanced(contextVersion);
387 
388     return true;
389 }