1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt3D module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "graphicshelpergl4_p.h"
41 
42 #ifndef QT_OPENGL_ES_2
43 #include <QOpenGLFunctions_4_3_Core>
44 #include <QtOpenGLExtensions/qopenglextensions.h>
45 #include <private/attachmentpack_p.h>
46 #include <qgraphicsutils_p.h>
47 #include <logging_p.h>
48 
49 # ifndef QT_OPENGL_4_3
50 #  ifndef GL_PATCH_VERTICES
51 #    define GL_PATCH_VERTICES 36466
52 #  endif
53 #  define GL_ACTIVE_RESOURCES 0x92F5
54 #  define GL_BUFFER_BINDING 0x9302
55 #  define GL_BUFFER_DATA_SIZE 0x9303
56 #  define GL_NUM_ACTIVE_VARIABLES 0x9304
57 #  define GL_SHADER_STORAGE_BLOCK 0x92E6
58 #  define GL_UNIFORM 0x92E1
59 #  define GL_UNIFORM_BLOCK 0x92E2
60 #  define GL_UNIFORM_BLOCK_INDEX 0x8A3A
61 #  define GL_UNIFORM_OFFSET 0x8A3B
62 #  define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
63 #  define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
64 #  define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
65 #  define GL_UNIFORM_BLOCK_BINDING 0x8A3F
66 #  define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
67 #  define GL_ALL_BARRIER_BITS 0xFFFFFFFF
68 #  define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
69 #  define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
70 #  define GL_UNIFORM_BARRIER_BIT 0x00000004
71 #  define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
72 #  define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
73 #  define GL_COMMAND_BARRIER_BIT 0x00000040
74 #  define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
75 #  define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
76 #  define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
77 #  define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
78 #  define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
79 #  define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
80 #  define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
81 #  define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
82 #  define GL_IMAGE_1D                       0x904C
83 #  define GL_IMAGE_2D                       0x904D
84 #  define GL_IMAGE_3D                       0x904E
85 #  define GL_IMAGE_2D_RECT                  0x904F
86 #  define GL_IMAGE_CUBE                     0x9050
87 #  define GL_IMAGE_BUFFER                   0x9051
88 #  define GL_IMAGE_1D_ARRAY                 0x9052
89 #  define GL_IMAGE_2D_ARRAY                 0x9053
90 #  define GL_IMAGE_CUBE_MAP_ARRAY           0x9054
91 #  define GL_IMAGE_2D_MULTISAMPLE           0x9055
92 #  define GL_IMAGE_2D_MULTISAMPLE_ARRAY     0x9056
93 #  define GL_INT_IMAGE_1D                   0x9057
94 #  define GL_INT_IMAGE_2D                   0x9058
95 #  define GL_INT_IMAGE_3D                   0x9059
96 #  define GL_INT_IMAGE_2D_RECT              0x905A
97 #  define GL_INT_IMAGE_CUBE                 0x905B
98 #  define GL_INT_IMAGE_BUFFER               0x905C
99 #  define GL_INT_IMAGE_1D_ARRAY             0x905D
100 #  define GL_INT_IMAGE_2D_ARRAY             0x905E
101 #  define GL_INT_IMAGE_CUBE_MAP_ARRAY       0x905F
102 #  define GL_INT_IMAGE_2D_MULTISAMPLE       0x9060
103 #  define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
104 #  define GL_UNSIGNED_INT_IMAGE_1D          0x9062
105 #  define GL_UNSIGNED_INT_IMAGE_2D          0x9063
106 #  define GL_UNSIGNED_INT_IMAGE_3D          0x9064
107 #  define GL_UNSIGNED_INT_IMAGE_2D_RECT     0x9065
108 #  define GL_UNSIGNED_INT_IMAGE_CUBE        0x9066
109 #  define GL_UNSIGNED_INT_IMAGE_BUFFER      0x9067
110 #  define GL_UNSIGNED_INT_IMAGE_1D_ARRAY    0x9068
111 #  define GL_UNSIGNED_INT_IMAGE_2D_ARRAY    0x9069
112 #  define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
113 #  define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
114 #  define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
115 # endif
116 
117 QT_BEGIN_NAMESPACE
118 
119 namespace Qt3DRender {
120 namespace Render {
121 namespace OpenGL {
122 
123 namespace {
124 
memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers)125 GLbitfield memoryBarrierGLBitfield(QMemoryBarrier::Operations barriers)
126 {
127     GLbitfield bits = 0;
128 
129     if (barriers.testFlag(QMemoryBarrier::All)) {
130         bits |= GL_ALL_BARRIER_BITS;
131         return bits;
132     }
133 
134     if (barriers.testFlag(QMemoryBarrier::VertexAttributeArray))
135         bits |= GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT;
136     if (barriers.testFlag(QMemoryBarrier::ElementArray))
137         bits |= GL_ELEMENT_ARRAY_BARRIER_BIT;
138     if (barriers.testFlag(QMemoryBarrier::Uniform))
139         bits |= GL_UNIFORM_BARRIER_BIT;
140     if (barriers.testFlag(QMemoryBarrier::TextureFetch))
141         bits |= GL_TEXTURE_FETCH_BARRIER_BIT;
142     if (barriers.testFlag(QMemoryBarrier::ShaderImageAccess))
143         bits |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
144     if (barriers.testFlag(QMemoryBarrier::Command))
145         bits |= GL_COMMAND_BARRIER_BIT;
146     if (barriers.testFlag(QMemoryBarrier::PixelBuffer))
147         bits |= GL_PIXEL_BUFFER_BARRIER_BIT;
148     if (barriers.testFlag(QMemoryBarrier::TextureUpdate))
149         bits |= GL_TEXTURE_UPDATE_BARRIER_BIT;
150     if (barriers.testFlag(QMemoryBarrier::BufferUpdate))
151         bits |= GL_BUFFER_UPDATE_BARRIER_BIT;
152     if (barriers.testFlag(QMemoryBarrier::FrameBuffer))
153         bits |= GL_FRAMEBUFFER_BARRIER_BIT;
154     if (barriers.testFlag(QMemoryBarrier::TransformFeedback))
155         bits |= GL_TRANSFORM_FEEDBACK_BARRIER_BIT;
156     if (barriers.testFlag(QMemoryBarrier::AtomicCounter))
157         bits |= GL_ATOMIC_COUNTER_BARRIER_BIT;
158     if (barriers.testFlag(QMemoryBarrier::ShaderStorage))
159         bits |= GL_SHADER_STORAGE_BARRIER_BIT;
160     if (barriers.testFlag(QMemoryBarrier::QueryBuffer))
161         bits |= GL_QUERY_BUFFER_BARRIER_BIT;
162 
163     return bits;
164 }
165 
166 }
167 
GraphicsHelperGL4()168 GraphicsHelperGL4::GraphicsHelperGL4()
169     : m_funcs(nullptr)
170 {
171 }
172 
initializeHelper(QOpenGLContext * context,QAbstractOpenGLFunctions * functions)173 void GraphicsHelperGL4::initializeHelper(QOpenGLContext *context,
174                                          QAbstractOpenGLFunctions *functions)
175 {
176     Q_UNUSED(context);
177     m_funcs = static_cast<QOpenGLFunctions_4_3_Core*>(functions);
178     const bool ok = m_funcs->initializeOpenGLFunctions();
179     Q_ASSERT(ok);
180     Q_UNUSED(ok);
181 }
182 
drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,GLsizei primitiveCount,GLint indexType,void * indices,GLsizei instances,GLint baseVertex,GLint baseInstance)183 void GraphicsHelperGL4::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
184                                                                     GLsizei primitiveCount,
185                                                                     GLint indexType,
186                                                                     void *indices,
187                                                                     GLsizei instances,
188                                                                     GLint baseVertex,
189                                                                     GLint baseInstance)
190 {
191     if (baseInstance != 0)
192         qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2";
193 
194     // glDrawElements OpenGL 3.1 or greater
195     m_funcs->glDrawElementsInstancedBaseVertex(primitiveType,
196                                                primitiveCount,
197                                                indexType,
198                                                indices,
199                                                instances,
200                                                baseVertex);
201 }
202 
drawArraysInstanced(GLenum primitiveType,GLint first,GLsizei count,GLsizei instances)203 void GraphicsHelperGL4::drawArraysInstanced(GLenum primitiveType,
204                                             GLint first,
205                                             GLsizei count,
206                                             GLsizei instances)
207 {
208     // glDrawArraysInstanced OpenGL 3.1 or greater
209     m_funcs->glDrawArraysInstanced(primitiveType,
210                                    first,
211                                    count,
212                                    instances);
213 }
214 
drawArraysInstancedBaseInstance(GLenum primitiveType,GLint first,GLsizei count,GLsizei instances,GLsizei baseInstance)215 void GraphicsHelperGL4::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance)
216 {
217     m_funcs->glDrawArraysInstancedBaseInstance(primitiveType,
218                                                first,
219                                                count,
220                                                instances,
221                                                baseInstance);
222 }
223 
drawElements(GLenum primitiveType,GLsizei primitiveCount,GLint indexType,void * indices,GLint baseVertex)224 void GraphicsHelperGL4::drawElements(GLenum primitiveType,
225                                      GLsizei primitiveCount,
226                                      GLint indexType,
227                                      void *indices,
228                                      GLint baseVertex)
229 {
230     m_funcs->glDrawElementsBaseVertex(primitiveType,
231                                       primitiveCount,
232                                       indexType,
233                                       indices,
234                                       baseVertex);
235 }
236 
drawElementsIndirect(GLenum mode,GLenum type,void * indirect)237 void GraphicsHelperGL4::drawElementsIndirect(GLenum mode,
238                                              GLenum type,
239                                              void *indirect)
240 {
241     m_funcs->glDrawElementsIndirect(mode, type, indirect);
242 }
243 
drawArrays(GLenum primitiveType,GLint first,GLsizei count)244 void GraphicsHelperGL4::drawArrays(GLenum primitiveType,
245                                    GLint first,
246                                    GLsizei count)
247 {
248     m_funcs->glDrawArrays(primitiveType,
249                           first,
250                           count);
251 }
252 
drawArraysIndirect(GLenum mode,void * indirect)253 void GraphicsHelperGL4::drawArraysIndirect(GLenum mode, void *indirect)
254 {
255     m_funcs->glDrawArraysIndirect(mode, indirect);
256 }
257 
setVerticesPerPatch(GLint verticesPerPatch)258 void GraphicsHelperGL4::setVerticesPerPatch(GLint verticesPerPatch)
259 {
260     m_funcs->glPatchParameteri(GL_PATCH_VERTICES, verticesPerPatch);
261 }
262 
useProgram(GLuint programId)263 void GraphicsHelperGL4::useProgram(GLuint programId)
264 {
265     m_funcs->glUseProgram(programId);
266 }
267 
programUniformsAndLocations(GLuint programId)268 QVector<ShaderUniform> GraphicsHelperGL4::programUniformsAndLocations(GLuint programId)
269 {
270     QVector<ShaderUniform> uniforms;
271 
272     GLint nbrActiveUniforms = 0;
273     m_funcs->glGetProgramInterfaceiv(programId, GL_UNIFORM, GL_ACTIVE_RESOURCES, &nbrActiveUniforms);
274     uniforms.reserve(nbrActiveUniforms);
275     char uniformName[256];
276     for (GLint i = 0; i < nbrActiveUniforms; ++i) {
277         ShaderUniform uniform;
278         GLsizei uniformNameLength = 0;
279         // Size is 1 for scalar and more for struct or arrays
280         // Type is the GL Type
281         m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength,
282                                     &uniform.m_size, &uniform.m_type, uniformName);
283         uniformName[sizeof(uniformName) - 1] = '\0';
284         uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName);
285         uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength);
286         // Work around for uniform array names that aren't returned with [0] by some drivers
287         if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]")))
288             uniform.m_name.append(QLatin1String("[0]"));
289         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &uniform.m_blockIndex);
290         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_OFFSET, &uniform.m_offset);
291         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_ARRAY_STRIDE, &uniform.m_arrayStride);
292         m_funcs->glGetActiveUniformsiv(programId, 1, (GLuint*)&i, GL_UNIFORM_MATRIX_STRIDE, &uniform.m_matrixStride);
293         uniform.m_rawByteSize = uniformByteSize(uniform);
294         uniforms.append(uniform);
295         qCDebug(Rendering) << uniform.m_name << "size" << uniform.m_size
296                            << " offset" << uniform.m_offset
297                            << " rawSize" << uniform.m_rawByteSize;
298     }
299 
300     return uniforms;
301 }
302 
programAttributesAndLocations(GLuint programId)303 QVector<ShaderAttribute> GraphicsHelperGL4::programAttributesAndLocations(GLuint programId)
304 {
305     QVector<ShaderAttribute> attributes;
306     GLint nbrActiveAttributes = 0;
307     m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes);
308     attributes.reserve(nbrActiveAttributes);
309     char attributeName[256];
310     for (GLint i = 0; i < nbrActiveAttributes; ++i) {
311         ShaderAttribute attribute;
312         GLsizei attributeNameLength = 0;
313         // Size is 1 for scalar and more for struct or arrays
314         // Type is the GL Type
315         m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength,
316                                    &attribute.m_size, &attribute.m_type, attributeName);
317         attributeName[sizeof(attributeName) - 1] = '\0';
318         attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName);
319         attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength);
320         attributes.append(attribute);
321     }
322     return attributes;
323 }
324 
programUniformBlocks(GLuint programId)325 QVector<ShaderUniformBlock> GraphicsHelperGL4::programUniformBlocks(GLuint programId)
326 {
327     QVector<ShaderUniformBlock> blocks;
328     GLint nbrActiveUniformsBlocks = 0;
329     m_funcs->glGetProgramInterfaceiv(programId, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveUniformsBlocks);
330     blocks.reserve(nbrActiveUniformsBlocks);
331     for (GLint i = 0; i < nbrActiveUniformsBlocks; ++i) {
332         QByteArray uniformBlockName(256, '\0');
333         GLsizei length = 0;
334         ShaderUniformBlock uniformBlock;
335         m_funcs->glGetProgramResourceName(programId, GL_UNIFORM_BLOCK, i, 256, &length, uniformBlockName.data());
336         uniformBlock.m_name = QString::fromUtf8(uniformBlockName.left(length));
337         uniformBlock.m_index = i;
338         GLenum prop = GL_BUFFER_BINDING;
339         m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_binding);
340         prop = GL_BUFFER_DATA_SIZE;
341         m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_size);
342         prop = GL_NUM_ACTIVE_VARIABLES;
343         m_funcs->glGetProgramResourceiv(programId, GL_UNIFORM_BLOCK, i, 1, &prop, 4, NULL, &uniformBlock.m_activeUniformsCount);
344         blocks.append(uniformBlock);
345     }
346     return blocks;
347 }
348 
programShaderStorageBlocks(GLuint programId)349 QVector<ShaderStorageBlock> GraphicsHelperGL4::programShaderStorageBlocks(GLuint programId)
350 {
351     QVector<ShaderStorageBlock> blocks;
352     GLint nbrActiveShaderStorageBlocks = 0;
353     m_funcs->glGetProgramInterfaceiv(programId, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &nbrActiveShaderStorageBlocks);
354     blocks.reserve(nbrActiveShaderStorageBlocks);
355     for (GLint i = 0; i < nbrActiveShaderStorageBlocks; ++i) {
356         QByteArray storageBlockName(256, '\0');
357         GLsizei length = 0;
358         ShaderStorageBlock storageBlock;
359         m_funcs->glGetProgramResourceName(programId, GL_SHADER_STORAGE_BLOCK, i, 256, &length, storageBlockName.data());
360         storageBlock.m_index = i;
361         storageBlock.m_name = QString::fromUtf8(storageBlockName.left(length));
362         GLenum prop = GL_BUFFER_BINDING;
363         m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_binding);
364         prop = GL_BUFFER_DATA_SIZE;
365         m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_size);
366         prop = GL_NUM_ACTIVE_VARIABLES;
367         m_funcs->glGetProgramResourceiv(programId, GL_SHADER_STORAGE_BLOCK, i, 1, &prop, 4, NULL, &storageBlock.m_activeVariablesCount);
368         blocks.push_back(storageBlock);
369     }
370     return blocks;
371 }
372 
vertexAttribDivisor(GLuint index,GLuint divisor)373 void GraphicsHelperGL4::vertexAttribDivisor(GLuint index, GLuint divisor)
374 {
375     m_funcs->glVertexAttribDivisor(index, divisor);
376 }
377 
vertexAttributePointer(GLenum shaderDataType,GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * pointer)378 void GraphicsHelperGL4::vertexAttributePointer(GLenum shaderDataType,
379                                                GLuint index,
380                                                GLint size,
381                                                GLenum type,
382                                                GLboolean normalized,
383                                                GLsizei stride,
384                                                const GLvoid *pointer)
385 {
386     switch (shaderDataType) {
387     case GL_FLOAT:
388     case GL_FLOAT_VEC2:
389     case GL_FLOAT_VEC3:
390     case GL_FLOAT_VEC4:
391     case GL_FLOAT_MAT2:
392     case GL_FLOAT_MAT2x3:
393     case GL_FLOAT_MAT2x4:
394     case GL_FLOAT_MAT3:
395     case GL_FLOAT_MAT3x2:
396     case GL_FLOAT_MAT3x4:
397     case GL_FLOAT_MAT4x2:
398     case GL_FLOAT_MAT4x3:
399     case GL_FLOAT_MAT4:
400         m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer);
401         break;
402 
403     case GL_INT:
404     case GL_INT_VEC2:
405     case GL_INT_VEC3:
406     case GL_INT_VEC4:
407     case GL_UNSIGNED_INT:
408     case GL_UNSIGNED_INT_VEC2:
409     case GL_UNSIGNED_INT_VEC3:
410     case GL_UNSIGNED_INT_VEC4:
411         m_funcs->glVertexAttribIPointer(index, size, type, stride, pointer);
412         break;
413 
414     case GL_DOUBLE:
415     case GL_DOUBLE_VEC2:
416     case GL_DOUBLE_VEC3:
417     case GL_DOUBLE_VEC4:
418         m_funcs->glVertexAttribLPointer(index, size, type, stride, pointer);
419         break;
420 
421     default:
422         qCWarning(Rendering) << "vertexAttribPointer: Unhandled type";
423         Q_UNREACHABLE();
424     }
425 }
426 
readBuffer(GLenum mode)427 void GraphicsHelperGL4::readBuffer(GLenum mode)
428 {
429     m_funcs->glReadBuffer(mode);
430 }
431 
drawBuffer(GLenum mode)432 void GraphicsHelperGL4::drawBuffer(GLenum mode)
433 {
434     m_funcs->glDrawBuffer(mode);
435 }
436 
fenceSync()437 void *GraphicsHelperGL4::fenceSync()
438 {
439     return m_funcs->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
440 }
441 
clientWaitSync(void * sync,GLuint64 nanoSecTimeout)442 void GraphicsHelperGL4::clientWaitSync(void *sync, GLuint64 nanoSecTimeout)
443 {
444     qDebug() << Q_FUNC_INFO << sync << static_cast<GLsync>(sync);
445     GLenum e = m_funcs->glClientWaitSync(static_cast<GLsync>(sync), GL_SYNC_FLUSH_COMMANDS_BIT, nanoSecTimeout);
446     qDebug() << e;
447 }
448 
waitSync(void * sync)449 void GraphicsHelperGL4::waitSync(void *sync)
450 {
451     m_funcs->glWaitSync(static_cast<GLsync>(sync), 0, GL_TIMEOUT_IGNORED);
452 }
453 
wasSyncSignaled(void * sync)454 bool GraphicsHelperGL4::wasSyncSignaled(void *sync)
455 {
456     GLint v = 0;
457     m_funcs->glGetSynciv(static_cast<GLsync>(sync),
458                          GL_SYNC_STATUS,
459                          sizeof(v),
460                          nullptr,
461                          &v);
462     return v == GL_SIGNALED;
463 }
464 
deleteSync(void * sync)465 void GraphicsHelperGL4::deleteSync(void *sync)
466 {
467     m_funcs->glDeleteSync(static_cast<GLsync>(sync));
468 }
469 
rasterMode(GLenum faceMode,GLenum rasterMode)470 void GraphicsHelperGL4::rasterMode(GLenum faceMode, GLenum rasterMode)
471 {
472     m_funcs->glPolygonMode(faceMode, rasterMode);
473 }
474 
glUniform1fv(GLint location,GLsizei count,const GLfloat * values)475 void GraphicsHelperGL4::glUniform1fv(GLint location, GLsizei count, const GLfloat *values)
476 {
477     m_funcs->glUniform1fv(location, count, values);
478 }
479 
glUniform2fv(GLint location,GLsizei count,const GLfloat * values)480 void GraphicsHelperGL4::glUniform2fv(GLint location, GLsizei count, const GLfloat *values)
481 {
482     m_funcs->glUniform2fv(location, count, values);
483 }
484 
glUniform3fv(GLint location,GLsizei count,const GLfloat * values)485 void GraphicsHelperGL4::glUniform3fv(GLint location, GLsizei count, const GLfloat *values)
486 {
487     m_funcs->glUniform3fv(location, count, values);
488 }
489 
glUniform4fv(GLint location,GLsizei count,const GLfloat * values)490 void GraphicsHelperGL4::glUniform4fv(GLint location, GLsizei count, const GLfloat *values)
491 {
492     m_funcs->glUniform4fv(location, count, values);
493 }
494 
glUniform1iv(GLint location,GLsizei count,const GLint * values)495 void GraphicsHelperGL4::glUniform1iv(GLint location, GLsizei count, const GLint *values)
496 {
497     m_funcs->glUniform1iv(location, count, values);
498 }
499 
glUniform2iv(GLint location,GLsizei count,const GLint * values)500 void GraphicsHelperGL4::glUniform2iv(GLint location, GLsizei count, const GLint *values)
501 {
502     m_funcs->glUniform2iv(location, count, values);
503 }
504 
glUniform3iv(GLint location,GLsizei count,const GLint * values)505 void GraphicsHelperGL4::glUniform3iv(GLint location, GLsizei count, const GLint *values)
506 {
507     m_funcs->glUniform3iv(location, count, values);
508 }
509 
glUniform4iv(GLint location,GLsizei count,const GLint * values)510 void GraphicsHelperGL4::glUniform4iv(GLint location, GLsizei count, const GLint *values)
511 {
512     m_funcs->glUniform4iv(location, count, values);
513 }
514 
glUniform1uiv(GLint location,GLsizei count,const GLuint * values)515 void GraphicsHelperGL4::glUniform1uiv(GLint location, GLsizei count, const GLuint *values)
516 {
517     m_funcs->glUniform1uiv(location, count, values);
518 }
519 
glUniform2uiv(GLint location,GLsizei count,const GLuint * values)520 void GraphicsHelperGL4::glUniform2uiv(GLint location, GLsizei count, const GLuint *values)
521 {
522     m_funcs->glUniform2uiv(location, count, values);
523 }
524 
glUniform3uiv(GLint location,GLsizei count,const GLuint * values)525 void GraphicsHelperGL4::glUniform3uiv(GLint location, GLsizei count, const GLuint *values)
526 {
527     m_funcs->glUniform3uiv(location, count, values);
528 }
529 
glUniform4uiv(GLint location,GLsizei count,const GLuint * values)530 void GraphicsHelperGL4::glUniform4uiv(GLint location, GLsizei count, const GLuint *values)
531 {
532     m_funcs->glUniform4uiv(location, count, values);
533 }
534 
glUniformMatrix2fv(GLint location,GLsizei count,const GLfloat * values)535 void GraphicsHelperGL4::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values)
536 {
537     m_funcs->glUniformMatrix2fv(location, count, false, values);
538 }
539 
glUniformMatrix3fv(GLint location,GLsizei count,const GLfloat * values)540 void GraphicsHelperGL4::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values)
541 {
542     m_funcs->glUniformMatrix3fv(location, count, false, values);
543 }
544 
glUniformMatrix4fv(GLint location,GLsizei count,const GLfloat * values)545 void GraphicsHelperGL4::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values)
546 {
547     m_funcs->glUniformMatrix4fv(location, count, false, values);
548 }
549 
glUniformMatrix2x3fv(GLint location,GLsizei count,const GLfloat * values)550 void GraphicsHelperGL4::glUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *values)
551 {
552     m_funcs->glUniformMatrix2x3fv(location, count, false, values);
553 }
554 
glUniformMatrix3x2fv(GLint location,GLsizei count,const GLfloat * values)555 void GraphicsHelperGL4::glUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *values)
556 {
557     m_funcs->glUniformMatrix3x2fv(location, count, false, values);
558 }
559 
glUniformMatrix2x4fv(GLint location,GLsizei count,const GLfloat * values)560 void GraphicsHelperGL4::glUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *values)
561 {
562     m_funcs->glUniformMatrix2x4fv(location, count, false, values);
563 }
564 
glUniformMatrix4x2fv(GLint location,GLsizei count,const GLfloat * values)565 void GraphicsHelperGL4::glUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *values)
566 {
567     m_funcs->glUniformMatrix4x2fv(location, count, false, values);
568 }
569 
glUniformMatrix3x4fv(GLint location,GLsizei count,const GLfloat * values)570 void GraphicsHelperGL4::glUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *values)
571 {
572     m_funcs->glUniformMatrix3x4fv(location, count, false, values);
573 }
574 
glUniformMatrix4x3fv(GLint location,GLsizei count,const GLfloat * values)575 void GraphicsHelperGL4::glUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *values)
576 {
577     m_funcs->glUniformMatrix4x3fv(location, count, false, values);
578 }
579 
uniformTypeFromGLType(GLenum type)580 UniformType GraphicsHelperGL4::uniformTypeFromGLType(GLenum type)
581 {
582     switch (type) {
583     case GL_FLOAT:
584         return UniformType::Float;
585     case GL_FLOAT_VEC2:
586         return UniformType::Vec2;
587     case GL_FLOAT_VEC3:
588         return UniformType::Vec3;
589     case GL_FLOAT_VEC4:
590         return UniformType::Vec4;
591     case GL_FLOAT_MAT2:
592         return UniformType::Mat2;
593     case GL_FLOAT_MAT3:
594         return UniformType::Mat3;
595     case GL_FLOAT_MAT4:
596         return UniformType::Mat4;
597     case GL_FLOAT_MAT2x3:
598         return UniformType::Mat2x3;
599     case GL_FLOAT_MAT3x2:
600         return UniformType::Mat3x2;
601     case GL_FLOAT_MAT2x4:
602         return UniformType::Mat2x4;
603     case GL_FLOAT_MAT4x2:
604         return UniformType::Mat4x2;
605     case GL_FLOAT_MAT3x4:
606         return UniformType::Mat3x4;
607     case GL_FLOAT_MAT4x3:
608         return UniformType::Mat4x3;
609     case GL_INT:
610         return UniformType::Int;
611     case GL_INT_VEC2:
612         return UniformType::IVec2;
613     case GL_INT_VEC3:
614         return UniformType::IVec3;
615     case GL_INT_VEC4:
616         return UniformType::IVec4;
617     case GL_UNSIGNED_INT:
618         return UniformType::UInt;
619     case GL_UNSIGNED_INT_VEC2:
620         return UniformType::UIVec2;
621     case GL_UNSIGNED_INT_VEC3:
622         return UniformType::UIVec3;
623     case GL_UNSIGNED_INT_VEC4:
624         return UniformType::UIVec4;
625     case GL_BOOL:
626         return UniformType::Bool;
627     case GL_BOOL_VEC2:
628         return UniformType::BVec2;
629     case GL_BOOL_VEC3:
630         return UniformType::BVec3;
631     case GL_BOOL_VEC4:
632         return UniformType::BVec4;
633 
634     case GL_SAMPLER_1D:
635     case GL_SAMPLER_1D_ARRAY:
636     case GL_SAMPLER_1D_SHADOW:
637     case GL_SAMPLER_1D_ARRAY_SHADOW:
638     case GL_SAMPLER_2D:
639     case GL_SAMPLER_2D_RECT:
640     case GL_SAMPLER_2D_SHADOW:
641     case GL_SAMPLER_2D_RECT_SHADOW:
642     case GL_SAMPLER_CUBE:
643     case GL_SAMPLER_CUBE_SHADOW:
644     case GL_SAMPLER_CUBE_MAP_ARRAY:
645     case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
646     case GL_SAMPLER_2D_ARRAY:
647     case GL_SAMPLER_2D_ARRAY_SHADOW:
648     case GL_SAMPLER_2D_MULTISAMPLE:
649     case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
650     case GL_SAMPLER_3D:
651     case GL_SAMPLER_BUFFER:
652     case GL_INT_SAMPLER_1D:
653     case GL_INT_SAMPLER_2D:
654     case GL_INT_SAMPLER_3D:
655     case GL_INT_SAMPLER_BUFFER:
656     case GL_INT_SAMPLER_2D_RECT:
657     case GL_INT_SAMPLER_CUBE:
658     case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
659     case GL_INT_SAMPLER_1D_ARRAY:
660     case GL_INT_SAMPLER_2D_ARRAY:
661     case GL_INT_SAMPLER_2D_MULTISAMPLE:
662     case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
663     case GL_UNSIGNED_INT_SAMPLER_1D:
664     case GL_UNSIGNED_INT_SAMPLER_2D:
665     case GL_UNSIGNED_INT_SAMPLER_3D:
666     case GL_UNSIGNED_INT_SAMPLER_BUFFER:
667     case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
668     case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
669     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
670     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
671     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
672     case GL_UNSIGNED_INT_SAMPLER_CUBE:
673     case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
674         return UniformType::Sampler;
675 
676     case GL_IMAGE_1D:
677     case GL_IMAGE_2D:
678     case GL_IMAGE_3D:
679     case GL_IMAGE_2D_RECT:
680     case GL_IMAGE_CUBE:
681     case GL_IMAGE_BUFFER:
682     case GL_IMAGE_1D_ARRAY:
683     case GL_IMAGE_2D_ARRAY:
684     case GL_IMAGE_CUBE_MAP_ARRAY:
685     case GL_IMAGE_2D_MULTISAMPLE:
686     case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
687     case GL_INT_IMAGE_1D:
688     case GL_INT_IMAGE_2D:
689     case GL_INT_IMAGE_3D:
690     case GL_INT_IMAGE_2D_RECT:
691     case GL_INT_IMAGE_CUBE:
692     case GL_INT_IMAGE_BUFFER:
693     case GL_INT_IMAGE_1D_ARRAY:
694     case GL_INT_IMAGE_2D_ARRAY:
695     case GL_INT_IMAGE_CUBE_MAP_ARRAY:
696     case GL_INT_IMAGE_2D_MULTISAMPLE:
697     case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
698     case GL_UNSIGNED_INT_IMAGE_1D:
699     case GL_UNSIGNED_INT_IMAGE_2D:
700     case GL_UNSIGNED_INT_IMAGE_3D:
701     case GL_UNSIGNED_INT_IMAGE_2D_RECT:
702     case GL_UNSIGNED_INT_IMAGE_CUBE:
703     case GL_UNSIGNED_INT_IMAGE_BUFFER:
704     case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
705     case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
706     case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
707     case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
708     case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
709         return UniformType::Image;
710 
711     default:
712         // TO DO: Add support for Doubles and Images
713         Q_UNREACHABLE();
714         return UniformType::Float;
715     }
716 }
717 
blendEquation(GLenum mode)718 void GraphicsHelperGL4::blendEquation(GLenum mode)
719 {
720     m_funcs->glBlendEquation(mode);
721 }
722 
blendFunci(GLuint buf,GLenum sfactor,GLenum dfactor)723 void GraphicsHelperGL4::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
724 {
725     m_funcs->glBlendFunci(buf, sfactor, dfactor);
726 }
727 
blendFuncSeparatei(GLuint buf,GLenum sRGB,GLenum dRGB,GLenum sAlpha,GLenum dAlpha)728 void GraphicsHelperGL4::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha)
729 {
730     m_funcs->glBlendFuncSeparatei(buf, sRGB, dRGB, sAlpha, dAlpha);
731 }
732 
alphaTest(GLenum,GLenum)733 void GraphicsHelperGL4::alphaTest(GLenum, GLenum)
734 {
735     qCWarning(Rendering) << "AlphaTest not available with OpenGL 3.2 core";
736 }
737 
depthTest(GLenum mode)738 void GraphicsHelperGL4::depthTest(GLenum mode)
739 {
740     m_funcs->glEnable(GL_DEPTH_TEST);
741     m_funcs->glDepthFunc(mode);
742 }
743 
depthMask(GLenum mode)744 void GraphicsHelperGL4::depthMask(GLenum mode)
745 {
746     m_funcs->glDepthMask(mode);
747 }
748 
depthRange(GLdouble nearValue,GLdouble farValue)749 void GraphicsHelperGL4::depthRange(GLdouble nearValue, GLdouble farValue)
750 {
751     m_funcs->glDepthRange(nearValue, farValue);
752 }
753 
frontFace(GLenum mode)754 void GraphicsHelperGL4::frontFace(GLenum mode)
755 {
756     m_funcs->glFrontFace(mode);
757 
758 }
759 
setMSAAEnabled(bool enabled)760 void GraphicsHelperGL4::setMSAAEnabled(bool enabled)
761 {
762     enabled ? m_funcs->glEnable(GL_MULTISAMPLE)
763             : m_funcs->glDisable(GL_MULTISAMPLE);
764 }
765 
setAlphaCoverageEnabled(bool enabled)766 void GraphicsHelperGL4::setAlphaCoverageEnabled(bool enabled)
767 {
768     enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE)
769             : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
770 }
771 
createFrameBufferObject()772 GLuint GraphicsHelperGL4::createFrameBufferObject()
773 {
774     GLuint id;
775     m_funcs->glGenFramebuffers(1, &id);
776     return id;
777 }
778 
releaseFrameBufferObject(GLuint frameBufferId)779 void GraphicsHelperGL4::releaseFrameBufferObject(GLuint frameBufferId)
780 {
781     m_funcs->glDeleteFramebuffers(1, &frameBufferId);
782 }
783 
bindFrameBufferObject(GLuint frameBufferId,FBOBindMode mode)784 void GraphicsHelperGL4::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
785 {
786     switch (mode) {
787     case FBODraw:
788         m_funcs->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBufferId);
789         return;
790     case FBORead:
791         m_funcs->glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBufferId);
792         return;
793     case FBOReadAndDraw:
794     default:
795         m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
796         return;
797     }
798 }
799 
bindImageTexture(GLuint imageUnit,GLuint texture,GLint mipLevel,GLboolean layered,GLint layer,GLenum access,GLenum format)800 void GraphicsHelperGL4::bindImageTexture(GLuint imageUnit, GLuint texture,
801                                          GLint mipLevel, GLboolean layered,
802                                          GLint layer, GLenum access, GLenum format)
803 {
804     m_funcs->glBindImageTexture(imageUnit,
805                                 texture,
806                                 mipLevel,
807                                 layered,
808                                 layer,
809                                 access,
810                                 format);
811 }
812 
boundFrameBufferObject()813 GLuint GraphicsHelperGL4::boundFrameBufferObject()
814 {
815     GLint id = 0;
816     m_funcs->glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &id);
817     return id;
818 }
819 
checkFrameBufferComplete()820 bool GraphicsHelperGL4::checkFrameBufferComplete()
821 {
822     return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
823 }
824 
frameBufferNeedsRenderBuffer(const Attachment & attachment)825 bool GraphicsHelperGL4::frameBufferNeedsRenderBuffer(const Attachment &attachment)
826 {
827     Q_UNUSED(attachment);
828     return false;
829 }
830 
bindFrameBufferAttachment(QOpenGLTexture * texture,const Attachment & attachment)831 void GraphicsHelperGL4::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
832 {
833     GLenum attr = GL_DEPTH_STENCIL_ATTACHMENT;
834 
835     if (attachment.m_point <= QRenderTargetOutput::Color15)
836         attr = GL_COLOR_ATTACHMENT0 + attachment.m_point;
837     else if (attachment.m_point == QRenderTargetOutput::Depth)
838         attr = GL_DEPTH_ATTACHMENT;
839     else if (attachment.m_point == QRenderTargetOutput::Stencil)
840         attr = GL_STENCIL_ATTACHMENT;
841 
842     texture->bind();
843     QOpenGLTexture::Target target = texture->target();
844     if (target == QOpenGLTexture::Target1DArray || target == QOpenGLTexture::Target2DArray ||
845             target == QOpenGLTexture::Target2DMultisampleArray || target == QOpenGLTexture::Target3D)
846         m_funcs->glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer);
847     else if (target == QOpenGLTexture::TargetCubeMapArray && attachment.m_face != QAbstractTexture::AllFaces)
848         m_funcs->glFramebufferTextureLayer( GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel, attachment.m_layer * 6 + (attachment.m_face - QAbstractTexture::CubeMapPositiveX));
849     else if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face != QAbstractTexture::AllFaces)
850         m_funcs->glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
851     else
852         m_funcs->glFramebufferTexture(GL_DRAW_FRAMEBUFFER, attr, texture->textureId(), attachment.m_mipLevel);
853     texture->release();
854 }
855 
bindFrameBufferAttachment(RenderBuffer * renderBuffer,const Attachment & attachment)856 void GraphicsHelperGL4::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment)
857 {
858     Q_UNUSED(renderBuffer);
859     Q_UNUSED(attachment);
860     Q_UNREACHABLE();
861 }
862 
supportsFeature(GraphicsHelperInterface::Feature feature) const863 bool GraphicsHelperGL4::supportsFeature(GraphicsHelperInterface::Feature feature) const
864 {
865     switch (feature) {
866     case MRT:
867     case Tessellation:
868     case UniformBufferObject:
869     case BindableFragmentOutputs:
870     case PrimitiveRestart:
871     case RenderBufferDimensionRetrieval:
872     case TextureDimensionRetrieval:
873     case ShaderStorageObject:
874     case Compute:
875     case DrawBuffersBlend:
876     case BlitFramebuffer:
877     case IndirectDrawing:
878     case MapBuffer:
879     case Fences:
880     case ShaderImage:
881         return true;
882     default:
883         return false;
884     }
885 }
886 
drawBuffers(GLsizei n,const int * bufs)887 void GraphicsHelperGL4::drawBuffers(GLsizei n, const int *bufs)
888 {
889     // Use QVarLengthArray here
890     QVarLengthArray<GLenum, 16> drawBufs(n);
891 
892     for (int i = 0; i < n; i++)
893         drawBufs[i] = GL_COLOR_ATTACHMENT0 + bufs[i];
894     m_funcs->glDrawBuffers(n, drawBufs.constData());
895 }
896 
bindFragDataLocation(GLuint shader,const QHash<QString,int> & outputs)897 void GraphicsHelperGL4::bindFragDataLocation(GLuint shader, const QHash<QString, int> &outputs)
898 {
899     for (auto it = outputs.begin(), end = outputs.end(); it != end; ++it)
900         m_funcs->glBindFragDataLocation(shader, it.value(), it.key().toStdString().c_str());
901 }
902 
bindUniformBlock(GLuint programId,GLuint uniformBlockIndex,GLuint uniformBlockBinding)903 void GraphicsHelperGL4::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
904 {
905     m_funcs->glUniformBlockBinding(programId, uniformBlockIndex, uniformBlockBinding);
906 }
907 
bindShaderStorageBlock(GLuint programId,GLuint shaderStorageBlockIndex,GLuint shaderStorageBlockBinding)908 void GraphicsHelperGL4::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
909 {
910     m_funcs->glShaderStorageBlockBinding(programId, shaderStorageBlockIndex, shaderStorageBlockBinding);
911 }
912 
bindBufferBase(GLenum target,GLuint index,GLuint buffer)913 void GraphicsHelperGL4::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
914 {
915     m_funcs->glBindBufferBase(target, index, buffer);
916 }
917 
buildUniformBuffer(const QVariant & v,const ShaderUniform & description,QByteArray & buffer)918 void GraphicsHelperGL4::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer)
919 {
920     char *bufferData = buffer.data();
921 
922     switch (description.m_type) {
923 
924     case GL_FLOAT: {
925         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 1);
926         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
927         break;
928     }
929 
930     case GL_FLOAT_VEC2: {
931         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 2);
932         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
933         break;
934     }
935 
936     case GL_FLOAT_VEC3: {
937         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 3);
938         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
939         break;
940     }
941 
942     case GL_FLOAT_VEC4: {
943         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4);
944         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
945         break;
946     }
947 
948     case GL_FLOAT_MAT2: {
949         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 4);
950         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 2);
951         break;
952     }
953 
954     case GL_FLOAT_MAT2x3: {
955         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6);
956         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 3);
957         break;
958     }
959 
960     case GL_FLOAT_MAT2x4: {
961         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8);
962         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 2, 4);
963         break;
964     }
965 
966     case GL_FLOAT_MAT3: {
967         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 9);
968         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 3);
969         break;
970     }
971 
972     case GL_FLOAT_MAT3x2: {
973         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 6);
974         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 2);
975         break;
976     }
977 
978     case GL_FLOAT_MAT3x4: {
979         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12);
980         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 3, 4);
981         break;
982     }
983 
984     case GL_FLOAT_MAT4: {
985         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 16);
986         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 4);
987         break;
988     }
989 
990     case GL_FLOAT_MAT4x2: {
991         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 8);
992         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 2);
993         break;
994     }
995 
996     case GL_FLOAT_MAT4x3: {
997         const GLfloat *data = QGraphicsUtils::valueArrayFromVariant<GLfloat>(v, description.m_size, 12);
998         QGraphicsUtils::fillDataMatrixArray(bufferData, data, description, 4, 3);
999         break;
1000     }
1001 
1002     case GL_INT: {
1003         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 1);
1004         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
1005         break;
1006     }
1007 
1008     case GL_INT_VEC2: {
1009         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 2);
1010         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
1011         break;
1012     }
1013 
1014     case GL_INT_VEC3: {
1015         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 3);
1016         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
1017         break;
1018     }
1019 
1020     case GL_INT_VEC4: {
1021         const GLint *data = QGraphicsUtils::valueArrayFromVariant<GLint>(v, description.m_size, 4);
1022         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
1023         break;
1024     }
1025 
1026     case GL_UNSIGNED_INT: {
1027         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 1);
1028         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
1029         break;
1030     }
1031 
1032     case GL_UNSIGNED_INT_VEC2: {
1033         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 2);
1034         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
1035         break;
1036     }
1037 
1038     case GL_UNSIGNED_INT_VEC3: {
1039         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 3);
1040         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
1041         break;
1042     }
1043 
1044     case GL_UNSIGNED_INT_VEC4: {
1045         const GLuint *data = QGraphicsUtils::valueArrayFromVariant<GLuint>(v, description.m_size, 4);
1046         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
1047         break;
1048     }
1049 
1050     case GL_BOOL: {
1051         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 1);
1052         QGraphicsUtils::fillDataArray(bufferData, data, description, 1);
1053         break;
1054     }
1055 
1056     case GL_BOOL_VEC2: {
1057         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 2);
1058         QGraphicsUtils::fillDataArray(bufferData, data, description, 2);
1059         break;
1060     }
1061 
1062     case GL_BOOL_VEC3: {
1063         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 3);
1064         QGraphicsUtils::fillDataArray(bufferData, data, description, 3);
1065         break;
1066     }
1067 
1068     case GL_BOOL_VEC4: {
1069         const GLboolean *data = QGraphicsUtils::valueArrayFromVariant<GLboolean>(v, description.m_size, 4);
1070         QGraphicsUtils::fillDataArray(bufferData, data, description, 4);
1071         break;
1072     }
1073 
1074     case GL_SAMPLER_1D:
1075     case GL_SAMPLER_2D:
1076     case GL_SAMPLER_3D:
1077     case GL_SAMPLER_CUBE:
1078     case GL_SAMPLER_BUFFER:
1079     case GL_SAMPLER_2D_RECT:
1080     case GL_INT_SAMPLER_1D:
1081     case GL_INT_SAMPLER_2D:
1082     case GL_INT_SAMPLER_3D:
1083     case GL_INT_SAMPLER_CUBE:
1084     case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
1085     case GL_INT_SAMPLER_BUFFER:
1086     case GL_INT_SAMPLER_2D_RECT:
1087     case GL_UNSIGNED_INT_SAMPLER_1D:
1088     case GL_UNSIGNED_INT_SAMPLER_2D:
1089     case GL_UNSIGNED_INT_SAMPLER_3D:
1090     case GL_UNSIGNED_INT_SAMPLER_CUBE:
1091     case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
1092     case GL_UNSIGNED_INT_SAMPLER_BUFFER:
1093     case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
1094     case GL_SAMPLER_1D_SHADOW:
1095     case GL_SAMPLER_2D_SHADOW:
1096     case GL_SAMPLER_CUBE_SHADOW:
1097     case GL_SAMPLER_CUBE_MAP_ARRAY:
1098     case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
1099     case GL_SAMPLER_1D_ARRAY:
1100     case GL_SAMPLER_2D_ARRAY:
1101     case GL_INT_SAMPLER_1D_ARRAY:
1102     case GL_INT_SAMPLER_2D_ARRAY:
1103     case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
1104     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1105     case GL_SAMPLER_1D_ARRAY_SHADOW:
1106     case GL_SAMPLER_2D_ARRAY_SHADOW:
1107     case GL_SAMPLER_2D_RECT_SHADOW:
1108     case GL_SAMPLER_2D_MULTISAMPLE:
1109     case GL_INT_SAMPLER_2D_MULTISAMPLE:
1110     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
1111     case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
1112     case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1113     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1114     case GL_IMAGE_1D:
1115     case GL_IMAGE_2D:
1116     case GL_IMAGE_3D:
1117     case GL_IMAGE_2D_RECT:
1118     case GL_IMAGE_CUBE:
1119     case GL_IMAGE_BUFFER:
1120     case GL_IMAGE_1D_ARRAY:
1121     case GL_IMAGE_2D_ARRAY:
1122     case GL_IMAGE_CUBE_MAP_ARRAY:
1123     case GL_IMAGE_2D_MULTISAMPLE:
1124     case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
1125     case GL_INT_IMAGE_1D:
1126     case GL_INT_IMAGE_2D:
1127     case GL_INT_IMAGE_3D:
1128     case GL_INT_IMAGE_2D_RECT:
1129     case GL_INT_IMAGE_CUBE:
1130     case GL_INT_IMAGE_BUFFER:
1131     case GL_INT_IMAGE_1D_ARRAY:
1132     case GL_INT_IMAGE_2D_ARRAY:
1133     case GL_INT_IMAGE_CUBE_MAP_ARRAY:
1134     case GL_INT_IMAGE_2D_MULTISAMPLE:
1135     case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1136     case GL_UNSIGNED_INT_IMAGE_1D:
1137     case GL_UNSIGNED_INT_IMAGE_2D:
1138     case GL_UNSIGNED_INT_IMAGE_3D:
1139     case GL_UNSIGNED_INT_IMAGE_2D_RECT:
1140     case GL_UNSIGNED_INT_IMAGE_CUBE:
1141     case GL_UNSIGNED_INT_IMAGE_BUFFER:
1142     case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
1143     case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
1144     case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
1145     case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
1146     case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY: {
1147         Q_ASSERT(description.m_size == 1);
1148         int value = v.toInt();
1149         QGraphicsUtils::fillDataArray<GLint>(bufferData, &value, description, 1);
1150         break;
1151     }
1152 
1153     default:
1154         qWarning() << Q_FUNC_INFO << "unsupported uniform type:" << description.m_type << "for " << description.m_name;
1155         break;
1156     }
1157 }
1158 
uniformByteSize(const ShaderUniform & description)1159 uint GraphicsHelperGL4::uniformByteSize(const ShaderUniform &description)
1160 {
1161     uint rawByteSize = 0;
1162     int arrayStride = qMax(description.m_arrayStride, 0);
1163     int matrixStride = qMax(description.m_matrixStride, 0);
1164 
1165     switch (description.m_type) {
1166 
1167     case GL_FLOAT_VEC2:
1168     case GL_INT_VEC2:
1169     case GL_UNSIGNED_INT_VEC2:
1170         rawByteSize = 8;
1171         break;
1172 
1173     case GL_FLOAT_VEC3:
1174     case GL_INT_VEC3:
1175     case GL_UNSIGNED_INT_VEC3:
1176         rawByteSize = 12;
1177         break;
1178 
1179     case GL_FLOAT_VEC4:
1180     case GL_INT_VEC4:
1181     case GL_UNSIGNED_INT_VEC4:
1182         rawByteSize = 16;
1183         break;
1184 
1185     case GL_FLOAT_MAT2:
1186         rawByteSize = matrixStride ? 2 * matrixStride : 16;
1187         break;
1188 
1189     case GL_FLOAT_MAT2x4:
1190         rawByteSize = matrixStride ? 2 * matrixStride : 32;
1191         break;
1192 
1193     case GL_FLOAT_MAT4x2:
1194         rawByteSize = matrixStride ? 4 * matrixStride : 32;
1195         break;
1196 
1197     case GL_FLOAT_MAT3:
1198         rawByteSize = matrixStride ? 3 * matrixStride : 36;
1199         break;
1200 
1201     case GL_FLOAT_MAT2x3:
1202         rawByteSize = matrixStride ? 2 * matrixStride : 24;
1203         break;
1204 
1205     case GL_FLOAT_MAT3x2:
1206         rawByteSize = matrixStride ? 3 * matrixStride : 24;
1207         break;
1208 
1209     case GL_FLOAT_MAT4:
1210         rawByteSize = matrixStride ? 4 * matrixStride : 64;
1211         break;
1212 
1213     case GL_FLOAT_MAT4x3:
1214         rawByteSize = matrixStride ? 4 * matrixStride : 48;
1215         break;
1216 
1217     case GL_FLOAT_MAT3x4:
1218         rawByteSize = matrixStride ? 3 * matrixStride : 48;
1219         break;
1220 
1221     case GL_BOOL:
1222         rawByteSize = 1;
1223         break;
1224 
1225     case GL_BOOL_VEC2:
1226         rawByteSize = 2;
1227         break;
1228 
1229     case GL_BOOL_VEC3:
1230         rawByteSize = 3;
1231         break;
1232 
1233     case GL_BOOL_VEC4:
1234         rawByteSize = 4;
1235         break;
1236 
1237     case GL_INT:
1238     case GL_FLOAT:
1239     case GL_UNSIGNED_INT:
1240     case GL_SAMPLER_1D:
1241     case GL_SAMPLER_2D:
1242     case GL_SAMPLER_3D:
1243     case GL_SAMPLER_CUBE:
1244     case GL_SAMPLER_BUFFER:
1245     case GL_SAMPLER_2D_RECT:
1246     case GL_INT_SAMPLER_1D:
1247     case GL_INT_SAMPLER_2D:
1248     case GL_INT_SAMPLER_3D:
1249     case GL_INT_SAMPLER_CUBE:
1250     case GL_INT_SAMPLER_BUFFER:
1251     case GL_INT_SAMPLER_2D_RECT:
1252     case GL_UNSIGNED_INT_SAMPLER_1D:
1253     case GL_UNSIGNED_INT_SAMPLER_2D:
1254     case GL_UNSIGNED_INT_SAMPLER_3D:
1255     case GL_UNSIGNED_INT_SAMPLER_CUBE:
1256     case GL_UNSIGNED_INT_SAMPLER_BUFFER:
1257     case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
1258     case GL_SAMPLER_1D_SHADOW:
1259     case GL_SAMPLER_2D_SHADOW:
1260     case GL_SAMPLER_CUBE_SHADOW:
1261     case GL_SAMPLER_CUBE_MAP_ARRAY:
1262     case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
1263     case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
1264     case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
1265     case GL_SAMPLER_1D_ARRAY:
1266     case GL_SAMPLER_2D_ARRAY:
1267     case GL_INT_SAMPLER_1D_ARRAY:
1268     case GL_INT_SAMPLER_2D_ARRAY:
1269     case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
1270     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
1271     case GL_SAMPLER_1D_ARRAY_SHADOW:
1272     case GL_SAMPLER_2D_ARRAY_SHADOW:
1273     case GL_SAMPLER_2D_RECT_SHADOW:
1274     case GL_SAMPLER_2D_MULTISAMPLE:
1275     case GL_INT_SAMPLER_2D_MULTISAMPLE:
1276     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
1277     case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
1278     case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1279     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
1280     case GL_IMAGE_1D:
1281     case GL_IMAGE_2D:
1282     case GL_IMAGE_3D:
1283     case GL_IMAGE_2D_RECT:
1284     case GL_IMAGE_CUBE:
1285     case GL_IMAGE_BUFFER:
1286     case GL_IMAGE_1D_ARRAY:
1287     case GL_IMAGE_2D_ARRAY:
1288     case GL_IMAGE_CUBE_MAP_ARRAY:
1289     case GL_IMAGE_2D_MULTISAMPLE:
1290     case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
1291     case GL_INT_IMAGE_1D:
1292     case GL_INT_IMAGE_2D:
1293     case GL_INT_IMAGE_3D:
1294     case GL_INT_IMAGE_2D_RECT:
1295     case GL_INT_IMAGE_CUBE:
1296     case GL_INT_IMAGE_BUFFER:
1297     case GL_INT_IMAGE_1D_ARRAY:
1298     case GL_INT_IMAGE_2D_ARRAY:
1299     case GL_INT_IMAGE_CUBE_MAP_ARRAY:
1300     case GL_INT_IMAGE_2D_MULTISAMPLE:
1301     case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1302     case GL_UNSIGNED_INT_IMAGE_1D:
1303     case GL_UNSIGNED_INT_IMAGE_2D:
1304     case GL_UNSIGNED_INT_IMAGE_3D:
1305     case GL_UNSIGNED_INT_IMAGE_2D_RECT:
1306     case GL_UNSIGNED_INT_IMAGE_CUBE:
1307     case GL_UNSIGNED_INT_IMAGE_BUFFER:
1308     case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
1309     case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
1310     case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
1311     case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
1312     case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
1313         rawByteSize = 4;
1314         break;
1315 
1316     default: {
1317         qWarning() << Q_FUNC_INFO << "unable to deduce rawByteSize for uniform type:" << description.m_type << "for uniform" << description.m_name;
1318         break;
1319     }
1320 
1321     }
1322 
1323     return arrayStride ? rawByteSize * arrayStride : rawByteSize;
1324 }
1325 
enableClipPlane(int clipPlane)1326 void GraphicsHelperGL4::enableClipPlane(int clipPlane)
1327 {
1328     m_funcs->glEnable(GL_CLIP_DISTANCE0 + clipPlane);
1329 }
1330 
disableClipPlane(int clipPlane)1331 void GraphicsHelperGL4::disableClipPlane(int clipPlane)
1332 {
1333     m_funcs->glDisable(GL_CLIP_DISTANCE0 + clipPlane);
1334 }
1335 
setClipPlane(int,const QVector3D &,float)1336 void GraphicsHelperGL4::setClipPlane(int, const QVector3D &, float)
1337 {
1338     // deprecated
1339 }
1340 
maxClipPlaneCount()1341 GLint GraphicsHelperGL4::maxClipPlaneCount()
1342 {
1343     GLint max = 0;
1344     m_funcs->glGetIntegerv(GL_MAX_CLIP_DISTANCES, &max);
1345     return max;
1346 }
1347 
memoryBarrier(QMemoryBarrier::Operations barriers)1348 void GraphicsHelperGL4::memoryBarrier(QMemoryBarrier::Operations barriers)
1349 {
1350     m_funcs->glMemoryBarrier(memoryBarrierGLBitfield(barriers));
1351 }
1352 
enablePrimitiveRestart(int primitiveRestartIndex)1353 void GraphicsHelperGL4::enablePrimitiveRestart(int primitiveRestartIndex)
1354 {
1355     m_funcs->glPrimitiveRestartIndex(primitiveRestartIndex);
1356     m_funcs->glEnable(GL_PRIMITIVE_RESTART);
1357 }
1358 
enableVertexAttributeArray(int location)1359 void GraphicsHelperGL4::enableVertexAttributeArray(int location)
1360 {
1361     m_funcs->glEnableVertexAttribArray(location);
1362 }
1363 
disablePrimitiveRestart()1364 void GraphicsHelperGL4::disablePrimitiveRestart()
1365 {
1366     m_funcs->glDisable(GL_PRIMITIVE_RESTART);
1367 }
1368 
clearBufferf(GLint drawbuffer,const QVector4D & values)1369 void GraphicsHelperGL4::clearBufferf(GLint drawbuffer, const QVector4D &values)
1370 {
1371     GLfloat vec[4] = {values[0], values[1], values[2], values[3]};
1372     m_funcs->glClearBufferfv(GL_COLOR, drawbuffer, vec);
1373 }
1374 
pointSize(bool programmable,GLfloat value)1375 void GraphicsHelperGL4::pointSize(bool programmable, GLfloat value)
1376 {
1377     if (programmable) {
1378         m_funcs->glEnable(GL_PROGRAM_POINT_SIZE);
1379     } else {
1380         m_funcs->glDisable(GL_PROGRAM_POINT_SIZE);
1381         m_funcs->glPointSize(value);
1382     }
1383 }
1384 
enablei(GLenum cap,GLuint index)1385 void GraphicsHelperGL4::enablei(GLenum cap, GLuint index)
1386 {
1387     m_funcs->glEnablei(cap, index);
1388 }
1389 
disablei(GLenum cap,GLuint index)1390 void GraphicsHelperGL4::disablei(GLenum cap, GLuint index)
1391 {
1392     m_funcs->glDisablei(cap, index);
1393 }
1394 
setSeamlessCubemap(bool enable)1395 void GraphicsHelperGL4::setSeamlessCubemap(bool enable)
1396 {
1397     if (enable)
1398         m_funcs->glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1399     else
1400         m_funcs->glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1401 }
1402 
getRenderBufferDimensions(GLuint renderBufferId)1403 QSize GraphicsHelperGL4::getRenderBufferDimensions(GLuint renderBufferId)
1404 {
1405     GLint width = 0;
1406     GLint height = 0;
1407 
1408     m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId);
1409     m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
1410     m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
1411     m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0);
1412 
1413     return QSize(width, height);
1414 }
1415 
getTextureDimensions(GLuint textureId,GLenum target,uint level)1416 QSize GraphicsHelperGL4::getTextureDimensions(GLuint textureId, GLenum target, uint level)
1417 {
1418     GLint width = 0;
1419     GLint height = 0;
1420 
1421     m_funcs->glBindTexture(target, textureId);
1422     m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
1423     m_funcs->glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
1424     m_funcs->glBindTexture(target, 0);
1425 
1426     return QSize(width, height);
1427 }
1428 
dispatchCompute(GLuint wx,GLuint wy,GLuint wz)1429 void GraphicsHelperGL4::dispatchCompute(GLuint wx, GLuint wy, GLuint wz)
1430 {
1431     m_funcs->glDispatchCompute(wx, wy, wz);
1432 }
1433 
mapBuffer(GLenum target,GLsizeiptr size)1434 char *GraphicsHelperGL4::mapBuffer(GLenum target, GLsizeiptr size)
1435 {
1436     return static_cast<char*>(m_funcs->glMapBufferRange(target, 0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
1437 }
1438 
unmapBuffer(GLenum target)1439 GLboolean GraphicsHelperGL4::unmapBuffer(GLenum target)
1440 {
1441     return m_funcs->glUnmapBuffer(target);
1442 }
1443 
blitFramebuffer(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)1444 void GraphicsHelperGL4::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
1445 {
1446     m_funcs->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1447 }
1448 
1449 } // namespace OpenGL
1450 } // namespace Render
1451 } // namespace Qt3DRender
1452 
1453 QT_END_NAMESPACE
1454 
1455 #endif // !QT_OPENGL_ES_2
1456