From 424207269539cce21241b7e5f4ab13a62d7e3f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 17 Aug 2014 14:53:45 +0200 Subject: [PATCH] Ensure that texture object is properly created before using it. As glGen*() only reserves object name without creating it, it must be ensured that the object is created before calling functions which expect already created object (such as glObjectLabel() or glBindTextures()). Allows me to remove quite a lot hacks in the tests. --- src/Magnum/AbstractTexture.cpp | 52 +++++++++++++++++-- src/Magnum/AbstractTexture.h | 8 ++- src/Magnum/Test/AbstractTextureGLTest.cpp | 11 ++-- src/Magnum/Test/BufferTextureGLTest.cpp | 13 ----- src/Magnum/Test/CubeMapTextureArrayGLTest.cpp | 9 ---- src/Magnum/Test/CubeMapTextureGLTest.cpp | 9 ---- src/Magnum/Test/MultisampleTextureGLTest.cpp | 16 ------ src/Magnum/Test/RectangleTextureGLTest.cpp | 9 ---- src/Magnum/Test/TextureArrayGLTest.cpp | 16 ------ src/Magnum/Test/TextureGLTest.cpp | 25 --------- 10 files changed, 57 insertions(+), 111 deletions(-) diff --git a/src/Magnum/AbstractTexture.cpp b/src/Magnum/AbstractTexture.cpp index 9d78a49ff..d5f1e7256 100644 --- a/src/Magnum/AbstractTexture.cpp +++ b/src/Magnum/AbstractTexture.cpp @@ -172,8 +172,9 @@ void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, std: /* Create array of IDs and also update bindings in state tracker */ Containers::Array ids{textures.size()}; Int i{}; - for(const AbstractTexture* const texture: textures) { - textureState->bindings[firstTextureUnit + i].second = ids[i] = texture ? texture->id() : 0; + for(AbstractTexture* const texture: textures) { + if(texture) texture->createIfNotAlready(); + textureState->bindings[firstTextureUnit + i].second = ids[i] = texture ? texture->_id : 0; ++i; } @@ -181,7 +182,7 @@ void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, std: } #endif -AbstractTexture::AbstractTexture(GLenum target): _target(target) { +AbstractTexture::AbstractTexture(GLenum target): _target{target}, _created{false} { glGenTextures(1, &_id); CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding); } @@ -197,11 +198,25 @@ AbstractTexture::~AbstractTexture() { glDeleteTextures(1, &_id); } -std::string AbstractTexture::label() const { +inline void AbstractTexture::createIfNotAlready() { + if(_created) return; + + /* glGen*() does not create the object, just reserves the name. Some + commands (such as glBindTextures() or glObjectLabel()) operate with IDs + directly and they require the object to be created. Binding the texture + to desired target finally creates it. Also all EXT DSA functions + implicitly create it. */ + bindInternal(); + CORRADE_INTERNAL_ASSERT(_created); +} + +std::string AbstractTexture::label() { + createIfNotAlready(); return Context::current()->state().debug->getLabelImplementation(GL_TEXTURE, _id); } AbstractTexture& AbstractTexture::setLabelInternal(const Containers::ArrayReference label) { + createIfNotAlready(); Context::current()->state().debug->labelImplementation(GL_TEXTURE, _id, label); return *this; } @@ -224,15 +239,19 @@ void AbstractTexture::bindImplementationDefault(GLint textureUnit) { if(textureState->currentTextureUnit != textureUnit) glActiveTexture(GL_TEXTURE0 + (textureState->currentTextureUnit = textureUnit)); + /* Binding the texture finally creates it */ + _created = true; glBindTexture(_target, _id); } #ifndef MAGNUM_TARGET_GLES void AbstractTexture::bindImplementationMulti(GLint textureUnit) { + createIfNotAlready(); glBindTextures(textureUnit, 1, &_id); } void AbstractTexture::bindImplementationDSA(GLint textureUnit) { + _created = true; glBindMultiTextureEXT(GL_TEXTURE0 + textureUnit, _target, _id); } #endif @@ -359,6 +378,7 @@ void AbstractTexture::mipmapImplementationDefault() { #ifndef MAGNUM_TARGET_GLES void AbstractTexture::mipmapImplementationDSA() { + _created = true; glGenerateTextureMipmapEXT(_id, _target); } #endif @@ -383,6 +403,9 @@ void AbstractTexture::bindInternal() { /* Bind the texture to internal unit if not already, update state tracker */ if(textureState->bindings[internalTextureUnit].second == _id) return; textureState->bindings[internalTextureUnit] = {_target, _id}; + + /* Binding the texture finally creates it */ + _created = true; glBindTexture(_target, _id); } @@ -764,6 +787,7 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLint val #ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLint value) { + _created = true; glTextureParameteriEXT(_id, _target, parameter, value); } #endif @@ -775,6 +799,7 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, GLfloat v #ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, GLfloat value) { + _created = true; glTextureParameterfEXT(_id, _target, parameter, value); } #endif @@ -787,6 +812,7 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLi #ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLint* values) { + _created = true; glTextureParameterivEXT(_id, _target, parameter, values); } #endif @@ -799,6 +825,7 @@ void AbstractTexture::parameterImplementationDefault(GLenum parameter, const GLf #ifndef MAGNUM_TARGET_GLES void AbstractTexture::parameterImplementationDSA(GLenum parameter, const GLfloat* values) { + _created = true; glTextureParameterfvEXT(_id, _target, parameter, values); } #endif @@ -810,6 +837,7 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL } void AbstractTexture::parameterIImplementationDSA(GLenum parameter, const GLuint* values) { + _created = true; glTextureParameterIuivEXT(_id, _target, parameter, values); } @@ -819,6 +847,7 @@ void AbstractTexture::parameterIImplementationDefault(GLenum parameter, const GL } void AbstractTexture::parameterIImplementationDSA(GLenum parameter, const GLint* values) { + _created = true; glTextureParameterIivEXT(_id, _target, parameter, values); } #endif @@ -837,6 +866,7 @@ void AbstractTexture::getLevelParameterImplementationDefault(GLenum target, GLin #ifndef MAGNUM_TARGET_GLES void AbstractTexture::getLevelParameterImplementationDSA(GLenum target, GLint level, GLenum parameter, GLint* values) { + _created = true; glGetTextureLevelParameterivEXT(_id, target, level, parameter, values); } #endif @@ -860,6 +890,7 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels } void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size) { + _created = true; glTextureStorage1DEXT(_id, target, levels, GLenum(internalFormat), size[0]); } #endif @@ -920,6 +951,7 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels #ifndef MAGNUM_TARGET_GLES void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size) { + _created = true; glTextureStorage2DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y()); } #endif @@ -974,6 +1006,7 @@ void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels #ifndef MAGNUM_TARGET_GLES void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size) { + _created = true; glTextureStorage3DEXT(_id, target, levels, GLenum(internalFormat), size.x(), size.y(), size.z()); } #endif @@ -994,6 +1027,7 @@ void AbstractTexture::storageMultisampleImplementationDefault(const GLenum targe #ifndef MAGNUM_TARGET_GLES void AbstractTexture::storageMultisampleImplementationDSA(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) { + _created = true; glTextureStorage2DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations); } @@ -1008,6 +1042,7 @@ void AbstractTexture::storageMultisampleImplementationDefault(const GLenum targe } void AbstractTexture::storageMultisampleImplementationDSA(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) { + _created = true; glTextureStorage3DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations); } #endif @@ -1019,6 +1054,7 @@ void AbstractTexture::getImageImplementationDefault(const GLenum target, const G } void AbstractTexture::getImageImplementationDSA(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) { + _created = true; glGetTextureImageEXT(_id, target, level, GLenum(format), GLenum(type), data); } @@ -1035,6 +1071,7 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Tex } void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { + _created = true; glTextureImage1DEXT(_id, target, level, GLint(internalFormat), size[0], 0, GLenum(format), GLenum(type), data); } #endif @@ -1046,6 +1083,7 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Tex #ifndef MAGNUM_TARGET_GLES void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { + _created = true; glTextureImage2DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), 0, GLenum(format), GLenum(type), data); } #endif @@ -1070,6 +1108,7 @@ void AbstractTexture::imageImplementationDefault(GLenum target, GLint level, Tex #ifndef MAGNUM_TARGET_GLES void AbstractTexture::imageImplementationDSA(GLenum target, GLint level, TextureFormat internalFormat, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { + _created = true; glTextureImage3DEXT(_id, target, level, GLint(internalFormat), size.x(), size.y(), size.z(), 0, GLenum(format), GLenum(type), data); } #endif @@ -1081,6 +1120,7 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, } void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Math::Vector<1, GLint>& offset, const Math::Vector<1, GLsizei>& size, ColorFormat format, ColorType type, const GLvoid* data) { + _created = true; glTextureSubImage1DEXT(_id, target, level, offset[0], size[0], GLenum(format), GLenum(type), data); } #endif @@ -1092,6 +1132,7 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, #ifndef MAGNUM_TARGET_GLES void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector2i& offset, const Vector2i& size, ColorFormat format, ColorType type, const GLvoid* data) { + _created = true; glTextureSubImage2DEXT(_id, target, level, offset.x(), offset.y(), size.x(), size.y(), GLenum(format), GLenum(type), data); } #endif @@ -1116,6 +1157,7 @@ void AbstractTexture::subImageImplementationDefault(GLenum target, GLint level, #ifndef MAGNUM_TARGET_GLES void AbstractTexture::subImageImplementationDSA(GLenum target, GLint level, const Vector3i& offset, const Vector3i& size, ColorFormat format, ColorType type, const GLvoid* data) { + _created = true; glTextureSubImage3DEXT(_id, target, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z(), GLenum(format), GLenum(type), data); } #endif @@ -1124,6 +1166,7 @@ void AbstractTexture::invalidateImageImplementationNoOp(GLint) {} #ifndef MAGNUM_TARGET_GLES void AbstractTexture::invalidateImageImplementationARB(GLint level) { + createIfNotAlready(); glInvalidateTexImage(_id, level); } #endif @@ -1132,6 +1175,7 @@ void AbstractTexture::invalidateSubImageImplementationNoOp(GLint, const Vector3i #ifndef MAGNUM_TARGET_GLES void AbstractTexture::invalidateSubImageImplementationARB(GLint level, const Vector3i& offset, const Vector3i& size) { + createIfNotAlready(); glInvalidateTexSubImage(_id, level, offset.x(), offset.y(), offset.z(), size.x(), size.y(), size.z()); } #endif diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index edc1f0816..2cdf30902 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -247,7 +247,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { * @fn_gl_extension2{GetObjectLabel,EXT,debug_label} with * @def_gl{TEXTURE} */ - std::string label() const; + std::string label(); /** * @brief Set texture label @@ -360,6 +360,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { static void MAGNUM_LOCAL bindImplementationMulti(GLint firstTextureUnit, std::initializer_list textures); #endif + void MAGNUM_LOCAL createIfNotAlready(); + void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit); #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit); @@ -484,6 +486,7 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { ColorType MAGNUM_LOCAL imageTypeForInternalFormat(TextureFormat internalFormat); GLuint _id; + bool _created; /* see createIfNotAlready() for details */ }; #ifndef DOXYGEN_GENERATING_OUTPUT @@ -587,13 +590,14 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> { }; #endif -inline AbstractTexture::AbstractTexture(AbstractTexture&& other) noexcept: _target(other._target), _id(other._id) { +inline AbstractTexture::AbstractTexture(AbstractTexture&& other) noexcept: _target{other._target}, _id{other._id}, _created{other._created} { other._id = 0; } inline AbstractTexture& AbstractTexture::operator=(AbstractTexture&& other) noexcept { std::swap(_target, other._target); std::swap(_id, other._id); + std::swap(_created, other._created); return *this; } diff --git a/src/Magnum/Test/AbstractTextureGLTest.cpp b/src/Magnum/Test/AbstractTextureGLTest.cpp index e5e6f39fe..9fd259e07 100644 --- a/src/Magnum/Test/AbstractTextureGLTest.cpp +++ b/src/Magnum/Test/AbstractTextureGLTest.cpp @@ -93,20 +93,15 @@ void AbstractTextureGLTest::label() { !Context::current()->isExtensionSupported()) CORRADE_SKIP("Required extension is not available"); - { - /** @todo Is this even legal optimization? */ - CORRADE_EXPECT_FAIL("The object must be used at least once before setting/querying label."); - CORRADE_VERIFY(false); - } Texture2D texture; - texture.setMinificationFilter(Sampler::Filter::Linear); CORRADE_COMPARE(texture.label(), ""); + MAGNUM_VERIFY_NO_ERROR(); texture.setLabel("MyTexture"); - CORRADE_COMPARE(texture.label(), "MyTexture"); - MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(texture.label(), "MyTexture"); } }} diff --git a/src/Magnum/Test/BufferTextureGLTest.cpp b/src/Magnum/Test/BufferTextureGLTest.cpp index 0789b2aaa..b67180ea9 100644 --- a/src/Magnum/Test/BufferTextureGLTest.cpp +++ b/src/Magnum/Test/BufferTextureGLTest.cpp @@ -67,19 +67,6 @@ void BufferTextureGLTest::bind() { CORRADE_SKIP(Extensions::GL::ARB::texture_buffer_object::string() + std::string(" is not supported.")); BufferTexture texture; - - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it"); - Buffer buffer; - constexpr UnsignedByte data[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f - }; - buffer.setData(data, BufferUsage::StaticDraw); - texture.setBuffer(BufferTextureFormat::R8UI, buffer); - CORRADE_VERIFY(false); - } - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp index 253c56ae2..908ae7cc9 100644 --- a/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureArrayGLTest.cpp @@ -103,15 +103,6 @@ void CubeMapTextureArrayGLTest::bind() { CORRADE_SKIP(Extensions::GL::ARB::texture_cube_map_array::string() + std::string(" is not supported.")); CubeMapTextureArray texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/CubeMapTextureGLTest.cpp b/src/Magnum/Test/CubeMapTextureGLTest.cpp index 5a7a23805..d93507960 100644 --- a/src/Magnum/Test/CubeMapTextureGLTest.cpp +++ b/src/Magnum/Test/CubeMapTextureGLTest.cpp @@ -128,15 +128,6 @@ void CubeMapTextureGLTest::construct() { void CubeMapTextureGLTest::bind() { CubeMapTexture texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/MultisampleTextureGLTest.cpp b/src/Magnum/Test/MultisampleTextureGLTest.cpp index e38fc50c3..0ccde3e5e 100644 --- a/src/Magnum/Test/MultisampleTextureGLTest.cpp +++ b/src/Magnum/Test/MultisampleTextureGLTest.cpp @@ -135,15 +135,6 @@ void MultisampleTextureGLTest::bind2D() { #endif MultisampleTexture2D texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setStorage(4, TextureFormat::RGBA8, {16, 16}); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); @@ -163,13 +154,6 @@ void MultisampleTextureGLTest::bind2DArray() { CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported.")); MultisampleTexture2DArray texture; - - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setStorage(4, TextureFormat::RGBA8, {16, 16, 5}); - CORRADE_VERIFY(false); - } - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/RectangleTextureGLTest.cpp b/src/Magnum/Test/RectangleTextureGLTest.cpp index 8bc4a3994..0bc52e25a 100644 --- a/src/Magnum/Test/RectangleTextureGLTest.cpp +++ b/src/Magnum/Test/RectangleTextureGLTest.cpp @@ -101,15 +101,6 @@ void RectangleTextureGLTest::bind() { CORRADE_SKIP(Extensions::GL::ARB::texture_rectangle::string() + std::string(" is not supported.")); RectangleTexture texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setWrapping(Sampler::Wrapping::ClampToEdge); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/TextureArrayGLTest.cpp b/src/Magnum/Test/TextureArrayGLTest.cpp index 3c0dec591..775bfcc91 100644 --- a/src/Magnum/Test/TextureArrayGLTest.cpp +++ b/src/Magnum/Test/TextureArrayGLTest.cpp @@ -233,13 +233,6 @@ void TextureArrayGLTest::bind1D() { CORRADE_SKIP(Extensions::GL::EXT::texture_array::string() + std::string(" is not supported.")); Texture1DArray texture; - - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); @@ -261,15 +254,6 @@ void TextureArrayGLTest::bind2D() { #endif Texture2DArray texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); diff --git a/src/Magnum/Test/TextureGLTest.cpp b/src/Magnum/Test/TextureGLTest.cpp index 04a786e11..7fe72cfb5 100644 --- a/src/Magnum/Test/TextureGLTest.cpp +++ b/src/Magnum/Test/TextureGLTest.cpp @@ -292,13 +292,6 @@ void TextureGLTest::construct3D() { #ifndef MAGNUM_TARGET_GLES void TextureGLTest::bind1D() { Texture1D texture; - - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); @@ -315,15 +308,6 @@ void TextureGLTest::bind1D() { void TextureGLTest::bind2D() { Texture2D texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR(); @@ -344,15 +328,6 @@ void TextureGLTest::bind3D() { #endif Texture3D texture; - - #ifndef MAGNUM_TARGET_GLES - if(Context::current()->isExtensionSupported()) { - CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it."); - texture.setBaseLevel(0); - CORRADE_VERIFY(false); - } - #endif - texture.bind(15); MAGNUM_VERIFY_NO_ERROR();