1/****************************************************************************
2**
3** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtOpenGL 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 "qopengltexturehelper_p.h"
41
42#include <QOpenGLContext>
43#include <private/qopenglextensions_p.h>
44
45QT_BEGIN_NAMESPACE
46
47QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
48{
49 functions = context->functions();
50 // Resolve EXT_direct_state_access entry points if present.
51
52 // However, disable it on some systems where DSA is known to be unreliable.
53 bool allowDSA = true;
54 const char *renderer = reinterpret_cast<const char *>(context->functions()->glGetString(GL_RENDERER));
55 // QTBUG-40653, QTBUG-44988
56 if (renderer && strstr(renderer, "AMD Radeon HD"))
57 allowDSA = false;
58
59 if (allowDSA && !context->isOpenGLES()
60 && context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
61 TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress("glTextureParameteriEXT"));
62 TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress("glTextureParameterivEXT"));
63 TextureParameterfEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLfloat )>(context->getProcAddress("glTextureParameterfEXT"));
64 TextureParameterfvEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLfloat *)>(context->getProcAddress("glTextureParameterfvEXT"));
65 GenerateTextureMipmapEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum )>(context->getProcAddress("glGenerateTextureMipmapEXT"));
66 TextureStorage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei )>(context->getProcAddress("glTextureStorage3DEXT"));
67 TextureStorage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei )>(context->getProcAddress("glTextureStorage2DEXT"));
68 TextureStorage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei )>(context->getProcAddress("glTextureStorage1DEXT"));
69 TextureStorage3DMultisampleEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTextureStorage3DMultisampleEXT"));
70 TextureStorage2DMultisampleEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTextureStorage2DMultisampleEXT"));
71 TextureImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTextureImage3DEXT"));
72 TextureImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTextureImage2DEXT"));
73 TextureImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTextureImage1DEXT"));
74 TextureSubImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTextureSubImage3DEXT"));
75 TextureSubImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTextureSubImage2DEXT"));
76 TextureSubImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTextureSubImage1DEXT"));
77 CompressedTextureSubImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTextureSubImage1DEXT"));
78 CompressedTextureSubImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTextureSubImage2DEXT"));
79 CompressedTextureSubImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTextureSubImage3DEXT"));
80 CompressedTextureImage1DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTextureImage1DEXT"));
81 CompressedTextureImage2DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTextureImage2DEXT"));
82 CompressedTextureImage3DEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTextureImage3DEXT"));
83
84 // Use the real DSA functions
85 TextureParameteri = &QOpenGLTextureHelper::dsa_TextureParameteri;
86 TextureParameteriv = &QOpenGLTextureHelper::dsa_TextureParameteriv;
87 TextureParameterf = &QOpenGLTextureHelper::dsa_TextureParameterf;
88 TextureParameterfv = &QOpenGLTextureHelper::dsa_TextureParameterfv;
89 GenerateTextureMipmap = &QOpenGLTextureHelper::dsa_GenerateTextureMipmap;
90 TextureStorage3D = &QOpenGLTextureHelper::dsa_TextureStorage3D;
91 TextureStorage2D = &QOpenGLTextureHelper::dsa_TextureStorage2D;
92 TextureStorage1D = &QOpenGLTextureHelper::dsa_TextureStorage1D;
93 TextureStorage3DMultisample = &QOpenGLTextureHelper::dsa_TextureStorage3DMultisample;
94 TextureStorage2DMultisample = &QOpenGLTextureHelper::dsa_TextureStorage2DMultisample;
95 TextureImage3D = &QOpenGLTextureHelper::dsa_TextureImage3D;
96 TextureImage2D = &QOpenGLTextureHelper::dsa_TextureImage2D;
97 TextureImage1D = &QOpenGLTextureHelper::dsa_TextureImage1D;
98 TextureSubImage3D = &QOpenGLTextureHelper::dsa_TextureSubImage3D;
99 TextureSubImage2D = &QOpenGLTextureHelper::dsa_TextureSubImage2D;
100 TextureSubImage1D = &QOpenGLTextureHelper::dsa_TextureSubImage1D;
101 CompressedTextureSubImage1D = &QOpenGLTextureHelper::dsa_CompressedTextureSubImage1D;
102 CompressedTextureSubImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureSubImage2D;
103 CompressedTextureSubImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureSubImage3D;
104 CompressedTextureImage1D = &QOpenGLTextureHelper::dsa_CompressedTextureImage1D;
105 CompressedTextureImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureImage2D;
106 CompressedTextureImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureImage3D;
107 } else {
108 // Use our own DSA emulation
109 TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri;
110 TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv;
111 TextureParameterf = &QOpenGLTextureHelper::qt_TextureParameterf;
112 TextureParameterfv = &QOpenGLTextureHelper::qt_TextureParameterfv;
113 GenerateTextureMipmap = &QOpenGLTextureHelper::qt_GenerateTextureMipmap;
114 TextureStorage3D = &QOpenGLTextureHelper::qt_TextureStorage3D;
115 TextureStorage2D = &QOpenGLTextureHelper::qt_TextureStorage2D;
116 TextureStorage1D = &QOpenGLTextureHelper::qt_TextureStorage1D;
117 TextureStorage3DMultisample = &QOpenGLTextureHelper::qt_TextureStorage3DMultisample;
118 TextureStorage2DMultisample = &QOpenGLTextureHelper::qt_TextureStorage2DMultisample;
119 TextureImage3D = &QOpenGLTextureHelper::qt_TextureImage3D;
120 TextureImage2D = &QOpenGLTextureHelper::qt_TextureImage2D;
121 TextureImage1D = &QOpenGLTextureHelper::qt_TextureImage1D;
122 TextureSubImage3D = &QOpenGLTextureHelper::qt_TextureSubImage3D;
123 TextureSubImage2D = &QOpenGLTextureHelper::qt_TextureSubImage2D;
124 TextureSubImage1D = &QOpenGLTextureHelper::qt_TextureSubImage1D;
125 CompressedTextureSubImage1D = &QOpenGLTextureHelper::qt_CompressedTextureSubImage1D;
126 CompressedTextureSubImage2D = &QOpenGLTextureHelper::qt_CompressedTextureSubImage2D;
127 CompressedTextureSubImage3D = &QOpenGLTextureHelper::qt_CompressedTextureSubImage3D;
128 CompressedTextureImage1D = &QOpenGLTextureHelper::qt_CompressedTextureImage1D;
129 CompressedTextureImage2D = &QOpenGLTextureHelper::qt_CompressedTextureImage2D;
130 CompressedTextureImage3D = &QOpenGLTextureHelper::qt_CompressedTextureImage3D;
131 }
132
133 // Some DSA functions are part of NV_texture_multisample instead
134 if (!context->isOpenGLES()
135 && context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
136 TextureImage3DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTextureImage3DMultisampleNV"));
137 TextureImage2DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTextureImage2DMultisampleNV"));
138
139 TextureImage3DMultisample = &QOpenGLTextureHelper::dsa_TextureImage3DMultisample;
140 TextureImage2DMultisample = &QOpenGLTextureHelper::dsa_TextureImage2DMultisample;
141 } else {
142 TextureImage3DMultisample = &QOpenGLTextureHelper::qt_TextureImage3DMultisample;
143 TextureImage2DMultisample = &QOpenGLTextureHelper::qt_TextureImage2DMultisample;
144 }
145
146#if QT_CONFIG(opengles2)
147 // Here we are targeting OpenGL ES 2.0+ only. This is likely using EGL, where,
148 // similarly to WGL, non-extension functions (i.e. any function that is part of the
149 // GLES spec) *may* not be queried via eglGetProcAddress.
150
151 // OpenGL 1.0
152 TexImage1D = 0;
153
154 // OpenGL 1.1
155 TexSubImage1D = 0;
156
157 // OpenGL 1.3
158 GetCompressedTexImage = 0;
159 CompressedTexSubImage1D = 0;
160 CompressedTexSubImage2D = ::glCompressedTexSubImage2D;
161 CompressedTexImage1D = 0;
162 CompressedTexImage2D = ::glCompressedTexImage2D;
163 ActiveTexture = ::glActiveTexture;
164
165 // OpenGL 3.0
166 GenerateMipmap = ::glGenerateMipmap;
167
168 // OpenGL 3.2
169 TexImage3DMultisample = 0;
170 TexImage2DMultisample = 0;
171
172 // OpenGL 4.2
173 QOpenGLContext *ctx = QOpenGLContext::currentContext();
174 if (ctx->format().majorVersion() >= 3) {
175 // OpenGL ES 3.0+ has immutable storage for 2D and 3D at least.
176 QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
177 TexStorage3D = extra->f.TexStorage3D;
178 TexStorage2D = extra->f.TexStorage2D;
179 } else {
180 TexStorage3D = 0;
181 TexStorage2D = 0;
182 }
183 TexStorage1D = 0;
184
185 // OpenGL 4.3
186 TexStorage3DMultisample = 0;
187 TexStorage2DMultisample = 0;
188 TexBufferRange = 0;
189 TextureView = 0;
190
191 // OpenGL ES 3.1+ has TexStorage2DMultisample
192 if (ctx->format().version() >= qMakePair(3, 1)) {
193 QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
194 TexStorage2DMultisample = extra->f.TexStorage2DMultisample;
195 }
196
197#endif
198
199 if (context->isOpenGLES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
200 TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress("glTexImage3DOES"));
201 TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress("glTexSubImage3DOES"));
202 CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress("glCompressedTexImage3DOES"));
203 CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress("glCompressedTexSubImage3DOES"));
204 } else {
205 QOpenGLContext *ctx = QOpenGLContext::currentContext();
206 if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) {
207 // OpenGL ES 3.0+ has glTexImage3D.
208 QOpenGLExtraFunctionsPrivate *extra = static_cast<QOpenGLExtensions *>(context->extraFunctions())->d();
209 TexImage3D = extra->f.TexImage3D;
210 TexSubImage3D = extra->f.TexSubImage3D;
211 CompressedTexImage3D = extra->f.CompressedTexImage3D;
212 CompressedTexSubImage3D = extra->f.CompressedTexSubImage3D;
213 } else {
214 // OpenGL 1.2
215 TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexImage3D"));
216 TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexSubImage3D"));
217
218 // OpenGL 1.3
219 CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTexImage3D"));
220 CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTexSubImage3D"));
221 }
222 }
223
224#if !QT_CONFIG(opengles2)
225 // OpenGL 1.0 and 1.1
226 TexImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexImage1D"));
227 TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexSubImage1D"));\
228
229 // OpenGL 1.3
230 GetCompressedTexImage = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLvoid *)>(context->getProcAddress("glGetCompressedTexImage"));
231 CompressedTexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTexSubImage1D"));
232 CompressedTexSubImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTexSubImage2D"));
233 CompressedTexImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTexImage1D"));
234 CompressedTexImage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress("glCompressedTexImage2D"));
235 ActiveTexture = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress("glActiveTexture"));
236
237 // OpenGL 3.0
238 GenerateMipmap = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress("glGenerateMipmap"));
239
240 // OpenGL 3.2
241 TexImage3DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTexImage3DMultisample"));
242 TexImage2DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTexImage2DMultisample"));
243
244 // OpenGL 4.2
245 TexStorage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei )>(context->getProcAddress("glTexStorage3D"));
246 TexStorage2D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei )>(context->getProcAddress("glTexStorage2D"));
247 TexStorage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei )>(context->getProcAddress("glTexStorage1D"));
248
249 // OpenGL 4.3
250 TexStorage3DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTexStorage3DMultisample"));
251 TexStorage2DMultisample = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLsizei , GLenum , GLsizei , GLsizei , GLboolean )>(context->getProcAddress("glTexStorage2DMultisample"));
252 TexBufferRange = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLenum , GLuint , GLintptr , GLsizeiptr )>(context->getProcAddress("glTexBufferRange"));
253 TextureView = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLuint , GLenum , GLuint , GLuint , GLuint , GLuint )>(context->getProcAddress("glTextureView"));
254#endif
255}
256
257void QOpenGLTextureHelper::dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
258{
259 Q_UNUSED(bindingTarget);
260 TextureParameteriEXT(texture, target, pname, param);
261}
262
263void QOpenGLTextureHelper::dsa_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
264{
265 Q_UNUSED(bindingTarget);
266 TextureParameterivEXT(texture, target, pname, params);
267}
268
269void QOpenGLTextureHelper::dsa_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
270{
271 Q_UNUSED(bindingTarget);
272 TextureParameterfEXT(texture, target, pname, param);
273}
274
275void QOpenGLTextureHelper::dsa_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
276{
277 Q_UNUSED(bindingTarget);
278 TextureParameterfvEXT(texture, target, pname, params);
279}
280
281void QOpenGLTextureHelper::dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
282{
283 Q_UNUSED(bindingTarget);
284 GenerateTextureMipmapEXT(texture, target);
285}
286
287void QOpenGLTextureHelper::dsa_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
288{
289 Q_UNUSED(bindingTarget);
290 TextureStorage3DEXT(texture, target, levels, internalFormat, width, height, depth);
291}
292
293void QOpenGLTextureHelper::dsa_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
294{
295 Q_UNUSED(bindingTarget);
296 TextureStorage2DEXT(texture, target, levels, internalFormat, width, height);
297}
298
299void QOpenGLTextureHelper::dsa_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
300{
301 Q_UNUSED(bindingTarget);
302 TextureStorage1DEXT(texture, target, levels, internalFormat, width);
303}
304
305void QOpenGLTextureHelper::dsa_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
306{
307 Q_UNUSED(bindingTarget);
308 TextureStorage3DMultisampleEXT(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
309}
310
311void QOpenGLTextureHelper::dsa_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
312{
313 Q_UNUSED(bindingTarget);
314 TextureStorage2DMultisampleEXT(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
315}
316
317void QOpenGLTextureHelper::dsa_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
318{
319 Q_UNUSED(bindingTarget);
320 TextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, format, type, pixels);
321}
322
323void QOpenGLTextureHelper::dsa_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
324{
325 Q_UNUSED(bindingTarget);
326 TextureImage2DEXT(texture, target, level, internalFormat, width, height, border, format, type, pixels);
327}
328
329void QOpenGLTextureHelper::dsa_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
330{
331 Q_UNUSED(bindingTarget);
332 TextureImage1DEXT(texture, target, level, internalFormat, width, border, format, type, pixels);
333}
334
335void QOpenGLTextureHelper::dsa_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
336{
337 Q_UNUSED(bindingTarget);
338 TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
339}
340
341void QOpenGLTextureHelper::dsa_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
342{
343 Q_UNUSED(bindingTarget);
344 TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels);
345}
346
347void QOpenGLTextureHelper::dsa_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
348{
349 Q_UNUSED(bindingTarget);
350 TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels);
351}
352
353void QOpenGLTextureHelper::dsa_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
354{
355 Q_UNUSED(bindingTarget);
356 TextureImage3DMultisampleNV(texture, target, samples, internalFormat, width, height, depth, fixedSampleLocations);
357}
358
359void QOpenGLTextureHelper::dsa_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
360{
361 Q_UNUSED(bindingTarget);
362 TextureImage2DMultisampleNV(texture, target, samples, internalFormat, width, height, fixedSampleLocations);
363}
364
365void QOpenGLTextureHelper::dsa_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
366{
367 Q_UNUSED(bindingTarget);
368 CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits);
369}
370
371void QOpenGLTextureHelper::dsa_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
372{
373 Q_UNUSED(bindingTarget);
374 CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits);
375}
376
377void QOpenGLTextureHelper::dsa_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
378{
379 Q_UNUSED(bindingTarget);
380 CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
381}
382
383void QOpenGLTextureHelper::dsa_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
384{
385 Q_UNUSED(bindingTarget);
386 CompressedTextureImage1DEXT(texture, target, level, internalFormat, width, border, imageSize, bits);
387}
388
389void QOpenGLTextureHelper::dsa_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
390{
391 Q_UNUSED(bindingTarget);
392 CompressedTextureImage2DEXT(texture, target, level, internalFormat, width, height, border, imageSize, bits);
393}
394
395void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
396{
397 Q_UNUSED(bindingTarget);
398 CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
399}
400
401namespace {
402
403class TextureBinder
404{
405public:
406 TextureBinder(QOpenGLFunctions *functions, GLuint texture, GLenum target, GLenum bindingTarget)
407 : m_functions(functions)
408 {
409 // For cubemaps we can't use the standard DSA emulation as it is illegal to
410 // try to bind a texture to one of the cubemap face targets. So we force the
411 // target and binding target to the cubemap values in this case.
412 switch (target) {
413 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
414 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
415 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
416 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
417 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
418 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
419 bindingTarget = GL_TEXTURE_BINDING_CUBE_MAP;
420 m_target = GL_TEXTURE_CUBE_MAP;
421 break;
422
423 default:
424 m_target = target;
425 break;
426 }
427
428 m_functions->glGetIntegerv(bindingTarget, &m_oldTexture);
429 m_functions->glBindTexture(m_target, texture);
430 }
431
432 ~TextureBinder()
433 {
434 m_functions->glBindTexture(m_target, m_oldTexture);
435 }
436
437private:
438 QOpenGLFunctions *m_functions;
439 GLenum m_target;
440 GLint m_oldTexture;
441};
442
443} // namespace
444
445void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
446{
447 TextureBinder binder(functions, texture, target, bindingTarget);
448 functions->glTexParameteri(target, pname, param);
449}
450
451void QOpenGLTextureHelper::qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params)
452{
453 TextureBinder binder(functions, texture, target, bindingTarget);
454 functions->glTexParameteriv(target, pname, params);
455}
456
457void QOpenGLTextureHelper::qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param)
458{
459 TextureBinder binder(functions, texture, target, bindingTarget);
460 functions->glTexParameterf(target, pname, param);
461}
462
463void QOpenGLTextureHelper::qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params)
464{
465 TextureBinder binder(functions, texture, target, bindingTarget);
466 functions->glTexParameterfv(target, pname, params);
467}
468
469void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget)
470{
471 TextureBinder binder(functions, texture, target, bindingTarget);
472 functions->glGenerateMipmap(target);
473}
474
475void QOpenGLTextureHelper::qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth)
476{
477 TextureBinder binder(functions, texture, target, bindingTarget);
478 glTexStorage3D(target, levels, internalFormat, width, height, depth);
479}
480
481void QOpenGLTextureHelper::qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height)
482{
483 TextureBinder binder(functions, texture, target, bindingTarget);
484 glTexStorage2D(target, levels, internalFormat, width, height);
485}
486
487void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
488{
489 TextureBinder binder(functions, texture, target, bindingTarget);
490 glTexStorage1D(target, levels, internalFormat, width);
491}
492
493void QOpenGLTextureHelper::qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
494{
495 TextureBinder binder(functions, texture, target, bindingTarget);
496 glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
497}
498
499void QOpenGLTextureHelper::qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
500{
501 TextureBinder binder(functions, texture, target, bindingTarget);
502 glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
503}
504
505void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
506{
507 TextureBinder binder(functions, texture, target, bindingTarget);
508 glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels);
509}
510
511void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
512{
513 TextureBinder binder(functions, texture, target, bindingTarget);
514 functions->glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
515}
516
517void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
518{
519 TextureBinder binder(functions, texture, target, bindingTarget);
520 glTexImage1D(target, level, internalFormat, width, border, format, type, pixels);
521}
522
523void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels)
524{
525 TextureBinder binder(functions, texture, target, bindingTarget);
526 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
527}
528
529void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
530{
531 TextureBinder binder(functions, texture, target, bindingTarget);
532 functions->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
533}
534
535void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
536{
537 TextureBinder binder(functions, texture, target, bindingTarget);
538 glTexSubImage1D(target, level, xoffset, width, format, type, pixels);
539}
540
541void QOpenGLTextureHelper::qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations)
542{
543 TextureBinder binder(functions, texture, target, bindingTarget);
544 glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations);
545}
546
547void QOpenGLTextureHelper::qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations)
548{
549 TextureBinder binder(functions, texture, target, bindingTarget);
550 glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations);
551}
552
553void QOpenGLTextureHelper::qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits)
554{
555 TextureBinder binder(functions, texture, target, bindingTarget);
556 glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits);
557}
558
559void QOpenGLTextureHelper::qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits)
560{
561 TextureBinder binder(functions, texture, target, bindingTarget);
562 glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits);
563}
564
565void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits)
566{
567 TextureBinder binder(functions, texture, target, bindingTarget);
568 glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits);
569}
570
571void QOpenGLTextureHelper::qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits)
572{
573 TextureBinder binder(functions, texture, target, bindingTarget);
574 glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits);
575}
576
577void QOpenGLTextureHelper::qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits)
578{
579 TextureBinder binder(functions, texture, target, bindingTarget);
580 glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits);
581}
582
583void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
584{
585 TextureBinder binder(functions, texture, target, bindingTarget);
586 glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
587}
588
589QT_END_NAMESPACE
590