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