| 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 | |
| 9 | QT_BEGIN_NAMESPACE |
| 10 | |
| 11 | QOpenGLTextureHelper::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 * = 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 | |
| 221 | void 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 | |
| 227 | void 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 | |
| 233 | void 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 | |
| 239 | void 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 | |
| 245 | void QOpenGLTextureHelper::dsa_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget) |
| 246 | { |
| 247 | Q_UNUSED(bindingTarget); |
| 248 | GenerateTextureMipmapEXT(texture, target); |
| 249 | } |
| 250 | |
| 251 | void 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 | |
| 257 | void 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 | |
| 263 | void 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 | |
| 269 | void 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 | |
| 275 | void 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 | |
| 281 | void 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 | |
| 287 | void 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 | |
| 293 | void 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 | |
| 299 | void 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 | |
| 305 | void 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 | |
| 311 | void 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 | |
| 317 | void 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 | |
| 323 | void 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 | |
| 329 | void 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 | |
| 335 | void 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 | |
| 341 | void 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 | |
| 347 | void 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 | |
| 353 | void 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 | |
| 359 | void 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 | |
| 365 | namespace { |
| 366 | |
| 367 | class TextureBinder |
| 368 | { |
| 369 | public: |
| 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 | |
| 401 | private: |
| 402 | QOpenGLFunctions *m_functions; |
| 403 | GLenum m_target; |
| 404 | GLint m_oldTexture; |
| 405 | }; |
| 406 | |
| 407 | } // namespace |
| 408 | |
| 409 | void 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 | |
| 415 | void 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 | |
| 421 | void 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 | |
| 427 | void 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 | |
| 433 | void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget) |
| 434 | { |
| 435 | TextureBinder binder(functions, texture, target, bindingTarget); |
| 436 | functions->glGenerateMipmap(target); |
| 437 | } |
| 438 | |
| 439 | void 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 | |
| 445 | void 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 | |
| 451 | void 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 | |
| 457 | void 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 | |
| 463 | void 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 | |
| 469 | void 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 | |
| 475 | void 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 | |
| 481 | void 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 | |
| 487 | void 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 | |
| 493 | void 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 | |
| 499 | void 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 | |
| 505 | void 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 | |
| 511 | void 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 | |
| 517 | void 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 | |
| 523 | void 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 | |
| 529 | void 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 | |
| 535 | void 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 | |
| 541 | void 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 | |
| 547 | void 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 | |
| 553 | QT_END_NAMESPACE |
| 554 | |