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_32;
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.gl32) {
15     enum has32 = true;
16 }
17 else enum has32 = false;
18 
19 // ARB_depth_clamp
20 version(GL_ARB) enum useARBDepthClamp = true;
21 else version(GL_ARB_depth_clamp) enum useARBDepthClamp = true;
22 else enum useARBDepthClamp = has32;
23 
24 static if(useARBDepthClamp) {
25     private bool _hasARBDepthClamp;
26     @nogc nothrow bool hasARBDepthClamp() { return _hasARBDepthClamp; }
27 
28     enum uint GL_DEPTH_CLAMP = 0x864F;
29 }
30 else enum hasARBDepthClamp = false;
31 
32 // ARB_provoking_vertex
33 version(GL_ARB) enum useARBProvokingVertex = true;
34 else version(GL_ARB_provoking_vertex) enum useARBProvokingVertex = true;
35 else enum useARBProvokingVertex = has32;
36 
37 static if(useARBProvokingVertex) {
38     private bool _hasARBProvokingVertex;
39     @nogc nothrow bool hasARBProvokingVertex() { return _hasARBProvokingVertex; }
40 
41     enum : uint {
42         GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION = 0x8E4C,
43         GL_FIRST_VERTEX_CONVENTION        = 0x8E4D,
44         GL_LAST_VERTEX_CONVENTION         = 0x8E4E,
45         GL_PROVOKING_VERTEX               = 0x8E4F,
46     }
47 
48     extern(System) @nogc nothrow {
49         alias pglProvokingVertex = void function(GLenum);
50     }
51 
52     __gshared {
53         pglProvokingVertex glProvokingVertex;
54     }
55 
56     private @nogc nothrow
57     bool loadARBProvokingVertex(SharedLib lib, GLSupport contextVersion)
58     {
59         lib.bindGLSymbol(cast(void**)&glProvokingVertex, "glProvokingVertex");
60         return resetErrorCountGL();
61     }
62 }
63 else enum hasARBProvokingVertex = false;
64 
65 // ARB_seamless_cube_map
66 version(GL_ARB) enum useARBSeamlessCubeMap = true;
67 else version(GL_ARB_seamless_cube_map) enum useARBSeamlessCubeMap = true;
68 else enum useARBSeamlessCubeMap = has32;
69 
70 static if(useARBSeamlessCubeMap) {
71     private bool _hasARBSeamlessCubeMap;
72     @nogc nothrow bool hasARBSeamlessCubeMap() { return _hasARBSeamlessCubeMap; }
73 
74     enum uint GL_TEXTURE_CUBE_MAP_SEAMLESS = 0x884F;
75 }
76 else enum hasARBSeamlessCubeMap = false;
77 
78 // ARB_draw_elements_base_vertex
79 version(GL_ARB) enum useARBDrawElementsBaseVertex = true;
80 else version(GL_ARB_draw_elements_base_vertex) enum useARBDrawElementsBaseVertex = true;
81 else enum useARBDrawElementsBaseVertex = has32;
82 
83 static if(useARBDrawElementsBaseVertex) {
84     private bool _hasARBDrawElementsBaseVertex;
85     @nogc nothrow bool hasARBDrawElementsBaseVertex() { return _hasARBDrawElementsBaseVertex; }
86 
87     extern(System) @nogc nothrow {
88         alias pglDrawElementsBaseVertex = void function(GLenum, GLsizei, GLenum, const(GLvoid)*, GLint);
89         alias pglDrawRangeElementsBaseVertex = void function(GLenum, GLuint, GLuint, GLsizei, GLenum, const(GLvoid)*, GLint);
90         alias pglDrawElementsInstancedBaseVertex = void function(GLenum, GLsizei, GLenum, const(GLvoid)*, GLsizei, GLint);
91         alias pglMultiDrawElementsBaseVertex = void function(GLenum, const(GLsizei)*, GLenum, const(GLvoid*)*, GLsizei, const(GLint)*);
92     }
93 
94     __gshared {
95         pglDrawElementsBaseVertex glDrawElementsBaseVertex;
96         pglDrawRangeElementsBaseVertex glDrawRangeElementsBaseVertex;
97         pglDrawElementsInstancedBaseVertex glDrawElementsInstancedBaseVertex;
98         pglMultiDrawElementsBaseVertex glMultiDrawElementsBaseVertex;
99     }
100 
101     private @nogc nothrow
102     bool loadARBDrawElementsBaseVertex(SharedLib lib, GLSupport contextVersion)
103     {
104         lib.bindGLSymbol(cast(void**)&glDrawElementsBaseVertex, "glDrawElementsBaseVertex");
105         lib.bindGLSymbol(cast(void**)&glDrawRangeElementsBaseVertex, "glDrawRangeElementsBaseVertex");
106         lib.bindGLSymbol(cast(void**)&glDrawElementsInstancedBaseVertex, "glDrawElementsInstancedBaseVertex");
107         lib.bindGLSymbol(cast(void**)&glMultiDrawElementsBaseVertex, "glMultiDrawElementsBaseVertex");
108         return resetErrorCountGL();
109     }
110 }
111 else enum hasARBDrawElementsBaseVertex = false;
112 
113 // ARB_sync
114 version(GL_ARB) enum useARBSync = true;
115 else version(GL_ARB_sync) enum useARBSync = true;
116 else enum useARBSync = has32;
117 
118 alias GLint64 = long;
119 alias GLuint64 = ulong;
120 struct __GLsync;
121 alias __GLsync* GLsync;
122 
123 static if(useARBSync) {
124     private bool _hasARBSync;
125     @nogc nothrow bool hasARBSync() { return _hasARBSync; }
126 
127     enum : uint {
128         GL_MAX_SERVER_WAIT_TIMEOUT        = 0x9111,
129         GL_OBJECT_TYPE                    = 0x9112,
130         GL_SYNC_CONDITION                 = 0x9113,
131         GL_SYNC_STATUS                    = 0x9114,
132         GL_SYNC_FLAGS                     = 0x9115,
133         GL_SYNC_FENCE                     = 0x9116,
134         GL_SYNC_GPU_COMMANDS_COMPLETE     = 0x9117,
135         GL_UNSIGNALED                     = 0x9118,
136         GL_SIGNALED                       = 0x9119,
137         GL_ALREADY_SIGNALED               = 0x911A,
138         GL_TIMEOUT_EXPIRED                = 0x911B,
139         GL_CONDITION_SATISFIED            = 0x911C,
140         GL_WAIT_FAILED                    = 0x911D,
141         GL_SYNC_FLUSH_COMMANDS_BIT        = 0x00000001,
142     }
143 
144     extern(System) @nogc nothrow {
145         alias pglFenceSync = GLsync function(GLenum, GLbitfield);
146         alias pglIsSync = GLboolean function(GLsync);
147         alias pglDeleteSync = void function(GLsync);
148         alias pglClientWaitSync = GLenum function(GLsync, GLbitfield, GLuint64);
149         alias pglWaitSync = void function(GLsync, GLbitfield, GLuint64);
150         alias pglGetInteger64v = void function(GLenum, GLint64*);
151         alias pglGetSynciv = void function(GLsync, GLenum, GLsizei, GLsizei*, GLint*);
152     }
153 
154     __gshared {
155         pglFenceSync glFenceSync;
156         pglIsSync glIsSync;
157         pglDeleteSync glDeleteSync;
158         pglClientWaitSync glClientWaitSync;
159         pglWaitSync glWaitSync;
160         pglGetInteger64v glGetInteger64v;
161         pglGetSynciv glGetSynciv;
162     }
163 
164     private @nogc nothrow
165     bool loadARBSync(SharedLib lib, GLSupport contextVersion)
166     {
167         lib.bindGLSymbol(cast(void**)&glFenceSync, "glFenceSync");
168         lib.bindGLSymbol(cast(void**)&glIsSync, "glIsSync");
169         lib.bindGLSymbol(cast(void**)&glDeleteSync, "glDeleteSync");
170         lib.bindGLSymbol(cast(void**)&glClientWaitSync, "glClientWaitSync");
171         lib.bindGLSymbol(cast(void**)&glWaitSync, "glWaitSync");
172         lib.bindGLSymbol(cast(void**)&glGetInteger64v, "glGetInteger64v");
173         lib.bindGLSymbol(cast(void**)&glGetSynciv, "glGetSynciv");
174         return resetErrorCountGL();
175     }
176 }
177 else enum hasARBSync = false;
178 
179 // ARB_texture_multisample
180 version(GL_ARB) enum useARBTextureMultiSample = true;
181 else version(GL_ARB_texture_multisample) enum useARBTextureMultiSample = true;
182 else enum useARBTextureMultiSample = has32;
183 
184 static if(useARBTextureMultiSample) {
185     private bool _hasARBTextureMultiSample;
186     @nogc nothrow bool hasARBTextureMultiSample() { return _hasARBTextureMultiSample; }
187 
188     enum : uint {
189         GL_SAMPLE_POSITION                = 0x8E50,
190         GL_SAMPLE_MASK                    = 0x8E51,
191         GL_SAMPLE_MASK_VALUE              = 0x8E52,
192         GL_MAX_SAMPLE_MASK_WORDS          = 0x8E59,
193         GL_TEXTURE_2D_MULTISAMPLE         = 0x9100,
194         GL_PROXY_TEXTURE_2D_MULTISAMPLE   = 0x9101,
195         GL_TEXTURE_2D_MULTISAMPLE_ARRAY   = 0x9102,
196         GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY = 0x9103,
197         GL_TEXTURE_BINDING_2D_MULTISAMPLE = 0x9104,
198         GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY = 0x9105,
199         GL_TEXTURE_SAMPLES                = 0x9106,
200         GL_TEXTURE_FIXED_SAMPLE_LOCATIONS = 0x9107,
201         GL_SAMPLER_2D_MULTISAMPLE         = 0x9108,
202         GL_INT_SAMPLER_2D_MULTISAMPLE     = 0x9109,
203         GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = 0x910A,
204         GL_SAMPLER_2D_MULTISAMPLE_ARRAY   = 0x910B,
205         GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910C,
206         GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = 0x910D,
207         GL_MAX_COLOR_TEXTURE_SAMPLES      = 0x910E,
208         GL_MAX_DEPTH_TEXTURE_SAMPLES      = 0x910F,
209         GL_MAX_INTEGER_SAMPLES            = 0x9110,
210     }
211 
212     extern(System) @nogc nothrow {
213         alias pglTexImage2DMultisample = void function(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean);
214         alias pglTexImage3DMultisample = void function(GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean);
215         alias pglGetMultisamplefv = void function(GLenum, GLuint, GLfloat*);
216         alias pglSampleMaski = void function(GLuint, GLbitfield);
217     }
218 
219     __gshared {
220         pglTexImage2DMultisample glTexImage2DMultisample;
221         pglTexImage3DMultisample glTexImage3DMultisample;
222         pglGetMultisamplefv glGetMultisamplefv;
223         pglSampleMaski glSampleMaski;
224     }
225 
226     private @nogc nothrow
227     bool loadTextureMultiSample(SharedLib lib, GLSupport contextVersion)
228     {
229         lib.bindGLSymbol(cast(void**)&glTexImage2DMultisample, "glTexImage2DMultisample");
230         lib.bindGLSymbol(cast(void**)&glTexImage3DMultisample, "glTexImage3DMultisample");
231         lib.bindGLSymbol(cast(void**)&glGetMultisamplefv, "glGetMultisamplefv");
232         lib.bindGLSymbol(cast(void**)&glSampleMaski, "glSampleMaski");
233         return resetErrorCountGL();
234     }
235 }
236 else enum hasARBTextureMultiSample = false;
237 
238 package(bindbc.opengl) @nogc nothrow
239 bool loadARB32(SharedLib lib, GLSupport contextVersion)
240 {
241     static if(has32) {
242         if(contextVersion >= GLSupport.gl32) {
243             _hasARBDepthClamp = true;
244             _hasARBSeamlessCubeMap = true;
245 
246             bool ret = true;
247             ret = _hasARBProvokingVertex = lib.loadARBProvokingVertex(contextVersion);
248             ret = _hasARBDrawElementsBaseVertex = lib.loadARBDrawElementsBaseVertex(contextVersion);
249             ret = _hasARBSync = lib.loadARBSync(contextVersion);
250             ret = _hasARBTextureMultiSample = lib.loadTextureMultiSample(contextVersion);
251             return ret;
252         }
253     }
254 
255     static if(useARBDepthClamp) _hasARBDepthClamp =
256             hasExtension(contextVersion, "GL_ARB_depth_clamp");
257 
258     static if(useARBProvokingVertex) _hasARBProvokingVertex =
259             hasExtension(contextVersion, "GL_ARB_provoking_vertex") &&
260             lib.loadARBProvokingVertex(contextVersion);
261 
262     static if(useARBSeamlessCubeMap) _hasARBSeamlessCubeMap =
263             hasExtension(contextVersion, "GL_ARB_seamless_cube_map");
264 
265     static if(useARBDrawElementsBaseVertex) _hasARBDrawElementsBaseVertex =
266             hasExtension(contextVersion, "GL_ARB_draw_elements_base_vertex") &&
267             lib.loadARBDrawElementsBaseVertex(contextVersion);
268 
269     static if(useARBSync) _hasARBSync =
270             hasExtension(contextVersion, "GL_ARB_sync") &&
271             lib.loadARBSync(contextVersion);
272 
273     static if(useARBTextureMultiSample) _hasARBTextureMultiSample =
274             hasExtension(contextVersion, "GL_ARB_texture_multisample") &&
275             lib.loadTextureMultiSample(contextVersion);
276 
277     return true;
278 }