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_44;
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.gl44) {
15     enum has44 = true;
16 }
17 else enum has44 = false;
18 
19 // ARB_buffer_storage
20 version(GL_ARB) enum useARBBufferStorage = true;
21 else version(GL_ARB_buffer_storage) enum useARBBufferStorage = true;
22 else enum useARBBufferStorage = has44;
23 
24 static if(useARBBufferStorage) {
25     private bool _hasARBBufferStorage;
26     @nogc nothrow bool hasARBBufferStorage() { return _hasARBBufferStorage; }
27 
28     enum : uint {
29         GL_MAP_PERSISTENT_BIT             = 0x0040,
30         GL_MAP_COHERENT_BIT               = 0x0080,
31         GL_DYNAMIC_STORAGE_BIT            = 0x0100,
32         GL_CLIENT_STORAGE_BIT             = 0x0200,
33         GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT = 0x00004000,
34         GL_BUFFER_IMMUTABLE_STORAGE       = 0x821F,
35         GL_BUFFER_STORAGE_FLAGS           = 0x8220,
36     }
37 
38     extern(System) @nogc nothrow {
39         alias pglBufferStorage = void function(GLenum,GLsizeiptr,const(void)*,GLbitfield);
40         alias pglNamedBufferStorageEXT = void function(GLuint,GLsizeiptr,const(void)*,GLbitfield);
41     }
42 
43     __gshared {
44         pglBufferStorage glBufferStorage;
45         pglNamedBufferStorageEXT glNamedBufferStorageEXT;
46     }
47 
48     private @nogc nothrow
49     bool loadARBBufferStorage(SharedLib lib, GLSupport contextVersion)
50     {
51         lib.bindGLSymbol(cast(void**)&glBufferStorage, "glBufferStorage");
52 
53         // The previous function is required when loading GL 4.3,
54         // the next one is not. Save the result of resetErrorCountGL and
55         // use that for the return value.
56         bool ret = resetErrorCountGL();
57         if(hasExtension(contextVersion, "GL_EXT_direct_state_access ")) {
58             lib.bindGLSymbol(cast(void**)&glNamedBufferStorageEXT, "glNamedBufferStorageEXT");
59 
60             // Ignore errors.
61             resetErrorCountGL();
62         }
63         return ret;
64     }
65 }
66 else enum hasARBBufferStorage = false;
67 
68 // ARB_clear_texture
69 version(GL_ARB) enum useARBClearTexture = true;
70 else version(GL_ARB_clear_texture) enum useARBClearTexture = true;
71 else enum useARBClearTexture = has44;
72 
73 static if(useARBClearTexture) {
74     private bool _hasARBClearTexture;
75     @nogc nothrow bool hasARBClearTexture() { return _hasARBClearTexture; }
76 
77     enum uint GL_CLEAR_TEXTURE = 0x9365;
78 
79     extern(System) @nogc nothrow {
80         alias pglClearTexImage = void function(GLuint,GLint,GLenum,GLenum,const(void)*);
81         alias pglClearTexSubImage = void function(GLuint,GLint,GLint,GLint,GLint,GLsizei,GLsizei,GLsizei,GLenum,GLenum,const(void)*);
82     }
83 
84     __gshared {
85         pglClearTexImage glClearTexImage;
86         pglClearTexSubImage glClearTexSubImage;
87     }
88 
89     private @nogc nothrow
90     bool loadARBClearTexture(SharedLib lib, GLSupport contextVersion)
91     {
92         lib.bindGLSymbol(cast(void**)&glClearTexImage, "glClearTexImage");
93         lib.bindGLSymbol(cast(void**)&glClearTexSubImage, "glClearTexSubImage");
94         return resetErrorCountGL();
95     }
96 }
97 else enum hasARBClearTexture = false;
98 
99 // ARB_enhanced_layouts
100 version(GL_ARB) enum useARBEnhancedLayouts = true;
101 else version(GL_ARB_enhanced_layouts) enum useARBEnhancedLayouts = true;
102 else enum useARBEnhancedLayouts = has44;
103 
104 static if(useARBEnhancedLayouts) {
105     private bool _hasARBEnhancedLayouts;
106     @nogc nothrow bool hasARBEnhancedLayouts() { return _hasARBEnhancedLayouts; }
107 
108     enum : uint  {
109         GL_LOCATION_COMPONENT             = 0x934A,
110         GL_TRANSFORM_FEEDBACK_BUFFER_INDEX = 0x934B,
111         GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE = 0x934C,
112     }
113 }
114 else enum hasARBEnhancedLayouts = false;
115 
116 // ARB_multi_bind
117 version(GL_ARB) enum useARBMultBind = true;
118 else version(GL_ARB_multi_bind) enum useARBMultBind = true;
119 else enum useARBMultBind = has44;
120 
121 static if(useARBMultBind) {
122     private bool _hasARBMultBind;
123     @nogc nothrow bool hasARBMultBind() { return _hasARBMultBind; }
124 
125     extern(System) @nogc nothrow {
126         alias pglBindBuffersBase = void function(GLenum,GLuint,GLsizei,const(GLuint)*);
127         alias pglBindBuffersRange = void function(GLenum,GLuint,GLsizei,const(GLuint)*,const(GLintptr)*,const(GLsizeiptr)*);
128         alias pglBindTextures = void function(GLuint,GLsizei,const(GLuint)*);
129         alias pglBindSamplers = void function(GLuint,GLsizei,const(GLuint)*);
130         alias pglBindImageTextures = void function(GLuint,GLsizei,const(GLuint)*);
131         alias pglBindVertexBuffers = void function(GLuint,GLsizei,const(GLuint)*,const(GLintptr)*,const(GLsizei)*);
132     }
133 
134     __gshared {
135         pglBindBuffersBase glBindBuffersBase;
136         pglBindBuffersRange glBindBuffersRange;
137         pglBindTextures glBindTextures;
138         pglBindSamplers glBindSamplers;
139         pglBindImageTextures glBindImageTextures;
140         pglBindVertexBuffers glBindVertexBuffers;
141     }
142 
143     private @nogc nothrow
144     bool loadARBMultBind(SharedLib lib, GLSupport contextVersion)
145     {
146         lib.bindGLSymbol(cast(void**)&glBindBuffersBase, "glBindBuffersBase");
147         lib.bindGLSymbol(cast(void**)&glBindBuffersRange, "glBindBuffersRange");
148         lib.bindGLSymbol(cast(void**)&glBindTextures, "glBindTextures");
149         lib.bindGLSymbol(cast(void**)&glBindSamplers, "glBindSamplers");
150         lib.bindGLSymbol(cast(void**)&glBindImageTextures, "glBindImageTextures");
151         lib.bindGLSymbol(cast(void**)&glBindVertexBuffers, "glBindVertexBuffers");
152         return resetErrorCountGL();
153     }
154 }
155 else enum hasARBMultBind = false;
156 
157 // ARB_query_buffer_object
158 version(GL_ARB) enum useARBQueryBufferObject = true;
159 else version(GL_ARB_query_buffer_object) enum useARBQueryBufferObject = true;
160 else enum useARBQueryBufferObject = has44;
161 
162 static if(useARBQueryBufferObject) {
163     private bool _hasARBQueryBufferObject;
164     @nogc nothrow bool hasARBQueryBufferObject() { return _hasARBQueryBufferObject; }
165 
166     enum : uint  {
167         GL_QUERY_BUFFER                   = 0x9192,
168         GL_QUERY_BUFFER_BARRIER_BIT       = 0x00008000,
169         GL_QUERY_BUFFER_BINDING           = 0x9193,
170         GL_QUERY_RESULT_NO_WAIT           = 0x9194,
171     }
172 }
173 else enum hasARBQueryBufferObject = false;
174 
175 // ARB_texture_mirror_clamp_to_edge
176 version(GL_ARB) enum useARBTextureMirrorClampToEdge = true;
177 else version(GL_ARB_texture_mirror_clamp_to_edge) enum useARBTextureMirrorClampToEdge = true;
178 else enum useARBTextureMirrorClampToEdge = has44;
179 
180 static if(useARBTextureMirrorClampToEdge) {
181     private bool _hasARBTextureMirrorClampToEdge;
182     @nogc nothrow bool hasARBTextureMirrorClampToEdge() { return _hasARBTextureMirrorClampToEdge; }
183 
184     enum uint GL_MIRROR_CLAMP_TO_EDGE = 0x8743;
185 }
186 else enum hasARBTextureMirrorClampToEdge = false;
187 
188 package(bindbc.opengl) @nogc nothrow
189 bool loadARB44(SharedLib lib, GLSupport contextVersion)
190 {
191     static if(has44) {
192         if(contextVersion >= GLSupport.gl44) {
193             _hasARBEnhancedLayouts = true;
194             _hasARBQueryBufferObject = true;
195             _hasARBTextureMirrorClampToEdge = true;
196 
197             bool ret = true;
198             ret = _hasARBBufferStorage = lib.loadARBBufferStorage(contextVersion);
199             ret = _hasARBClearTexture = lib.loadARBClearTexture(contextVersion);
200             ret = _hasARBMultBind = lib.loadARBMultBind(contextVersion);
201             return ret;
202         }
203     }
204 
205     static if(useARBEnhancedLayouts) _hasARBEnhancedLayouts =
206             hasExtension(contextVersion, "GL_ARB_enhanced_layouts");
207 
208     static if(useARBQueryBufferObject) _hasARBQueryBufferObject =
209             hasExtension(contextVersion, "GL_ARB_query_buffer_object");
210 
211     static if(useARBTextureMirrorClampToEdge) _hasARBTextureMirrorClampToEdge =
212             hasExtension(contextVersion, "GL_ARB_texture_mirror_clamp_to_edge");
213 
214     static if(useARBBufferStorage) _hasARBBufferStorage =
215             hasExtension(contextVersion, "GL_ARB_buffer_storage") &&
216             lib.loadARBBufferStorage(contextVersion);
217 
218     static if(useARBClearTexture) _hasARBClearTexture =
219             hasExtension(contextVersion, "GL_ARB_clear_texture") &&
220             lib.loadARBClearTexture(contextVersion);
221 
222     static if(useARBMultBind) _hasARBMultBind =
223             hasExtension(contextVersion, "GL_ARB_multi_bind") &&
224             lib.loadARBMultBind(contextVersion);
225 
226     return true;
227 }