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

source code of qtbase/src/opengl/qopengltexturehelper.cpp