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

source code of qt3d/src/plugins/renderers/opengl/graphicshelpers/graphicshelpergl4.cpp