Browse Source

Support ARB_multi_bind for textures.

pull/51/head
Vladimír Vondruš 12 years ago
parent
commit
cc66fa76ba
  1. 2
      doc/opengl-support.dox
  2. 30
      src/Magnum/AbstractTexture.cpp
  3. 21
      src/Magnum/AbstractTexture.h
  4. 3
      src/Magnum/Implementation/TextureState.cpp
  5. 1
      src/Magnum/Implementation/TextureState.h
  6. 4
      src/Magnum/Test/BufferTextureGLTest.cpp
  7. 4
      src/Magnum/Test/CubeMapTextureArrayGLTest.cpp
  8. 4
      src/Magnum/Test/CubeMapTextureGLTest.cpp
  9. 8
      src/Magnum/Test/MultisampleTextureGLTest.cpp
  10. 4
      src/Magnum/Test/RectangleTextureGLTest.cpp
  11. 8
      src/Magnum/Test/TextureArrayGLTest.cpp
  12. 12
      src/Magnum/Test/TextureGLTest.cpp

2
doc/opengl-support.dox

@ -201,7 +201,7 @@ following:
@extension{ARB,buffer_storage} | |
@extension{ARB,clear_texture} | |
@extension{ARB,enhanced_layouts} | done (shading language only)
@extension{ARB,multi_bind} | only single texture binding
@extension{ARB,multi_bind} | only texture binding
@extension{ARB,query_buffer_object} | |
@extension{ARB,texture_mirror_clamp_to_edge} | done
@extension{ARB,texture_stencil8} | done

30
src/Magnum/AbstractTexture.cpp

@ -127,6 +127,36 @@ void AbstractTexture::unbindImplementationDSA(const GLint textureUnit) {
}
#endif
void AbstractTexture::bind(const Int firstTextureUnit, std::initializer_list<AbstractTexture*> textures) {
/* State tracker is updated in the implementations */
Context::current()->state().texture->bindMultiImplementation(firstTextureUnit, textures);
}
void AbstractTexture::bindImplementationFallback(const GLint firstTextureUnit, std::initializer_list<AbstractTexture*> textures) {
Int unit = firstTextureUnit;
for(AbstractTexture* const texture: textures) {
if(texture) texture->bind(unit);
else unbind(unit);
++unit;
}
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::bindImplementationMulti(const GLint firstTextureUnit, std::initializer_list<AbstractTexture*> textures) {
Implementation::TextureState* const textureState = Context::current()->state().texture;
/* Create array of IDs and also update bindings in state tracker */
Containers::Array<GLuint> ids{textures.size()};
Int i{};
for(const AbstractTexture* const texture: textures) {
textureState->bindings[firstTextureUnit + i].second = ids[i] = texture ? texture->id() : 0;
++i;
}
glBindTextures(firstTextureUnit, ids.size(), ids);
}
#endif
AbstractTexture::AbstractTexture(GLenum target): _target(target) {
glGenTextures(1, &_id);
}

21
src/Magnum/AbstractTexture.h

@ -172,6 +172,19 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
*/
static void unbind(Int textureUnit);
/**
* @brief Bind textures to given range of texture units
*
* Binds first texture in the list to @p firstTextureUnit, second to
* `firstTextureUnit + 1` etc. If any texture is `nullptr`, given
* texture unit is unbound. If @extension{ARB,multi_bind} (part of
* OpenGL 4.4) is not available, the feature is emulated with sequence
* of @ref bind(Int) / @ref unbind() calls.
* @see @fn_gl{BindTextures}, eventually @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/
static void bind(Int firstTextureUnit, std::initializer_list<AbstractTexture*> textures);
/** @brief Copying is not allowed */
AbstractTexture(const AbstractTexture&) = delete;
@ -230,7 +243,8 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
* @note This function is meant to be used only internally from
* @ref AbstractShaderProgram subclasses. See its documentation
* for more information.
* @see @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(),
* @see @ref bind(Int, std::initializer_list<AbstractTexture*>),
* @ref unbind(), @ref Shader::maxCombinedTextureImageUnits(),
* @fn_gl{ActiveTexture}, @fn_gl{BindTexture}, @fn_gl{BindTextures}
* or @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/
@ -275,6 +289,11 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
static void MAGNUM_LOCAL unbindImplementationDSA(GLint textureUnit);
#endif
static void MAGNUM_LOCAL bindImplementationFallback(GLint firstTextureUnit, std::initializer_list<AbstractTexture*> textures);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL bindImplementationMulti(GLint firstTextureUnit, std::initializer_list<AbstractTexture*> textures);
#endif
void MAGNUM_LOCAL bindImplementationDefault(GLint textureUnit);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL bindImplementationMulti(GLint textureUnit);

3
src/Magnum/Implementation/TextureState.cpp

@ -47,18 +47,21 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
extensions.push_back(Extensions::GL::ARB::multi_bind::string());
unbindImplementation = &AbstractTexture::unbindImplementationMulti;
bindMultiImplementation = &AbstractTexture::bindImplementationMulti;
bindImplementation = &AbstractTexture::bindImplementationMulti;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Extension name added below */
unbindImplementation = &AbstractTexture::unbindImplementationDSA;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
bindImplementation = &AbstractTexture::bindImplementationDSA;
} else
#endif
{
unbindImplementation = &AbstractTexture::unbindImplementationDefault;
bindMultiImplementation = &AbstractTexture::bindImplementationFallback;
bindImplementation = &AbstractTexture::bindImplementationDefault;
}

1
src/Magnum/Implementation/TextureState.h

@ -38,6 +38,7 @@ struct TextureState {
~TextureState();
void(*unbindImplementation)(GLint);
void(*bindMultiImplementation)(GLint, std::initializer_list<AbstractTexture*>);
void(AbstractTexture::*bindImplementation)(GLint);
void(AbstractTexture::*parameteriImplementation)(GLenum, GLint);
void(AbstractTexture::*parameterfImplementation)(GLenum, GLfloat);

4
src/Magnum/Test/BufferTextureGLTest.cpp

@ -74,6 +74,10 @@ void BufferTextureGLTest::bind() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void BufferTextureGLTest::setBuffer() {

4
src/Magnum/Test/CubeMapTextureArrayGLTest.cpp

@ -101,6 +101,10 @@ void CubeMapTextureArrayGLTest::bind() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void CubeMapTextureArrayGLTest::sampling() {

4
src/Magnum/Test/CubeMapTextureGLTest.cpp

@ -121,6 +121,10 @@ void CubeMapTextureGLTest::bind() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void CubeMapTextureGLTest::sampling() {

8
src/Magnum/Test/MultisampleTextureGLTest.cpp

@ -127,6 +127,10 @@ void MultisampleTextureGLTest::bind2D() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::bind2DArray() {
@ -141,6 +145,10 @@ void MultisampleTextureGLTest::bind2DArray() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::storage2D() {

4
src/Magnum/Test/RectangleTextureGLTest.cpp

@ -102,6 +102,10 @@ void RectangleTextureGLTest::bind() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void RectangleTextureGLTest::sampling() {

8
src/Magnum/Test/TextureArrayGLTest.cpp

@ -212,6 +212,10 @@ void TextureArrayGLTest::bind1D() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
#endif
@ -229,6 +233,10 @@ void TextureArrayGLTest::bind2D() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES

12
src/Magnum/Test/TextureGLTest.cpp

@ -261,6 +261,10 @@ void TextureGLTest::bind1D() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
#endif
@ -273,6 +277,10 @@ void TextureGLTest::bind2D() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
void TextureGLTest::bind3D() {
@ -289,6 +297,10 @@ void TextureGLTest::bind3D() {
AbstractTexture::unbind(15);
MAGNUM_VERIFY_NO_ERROR();
AbstractTexture::bind(7, {&texture, nullptr, &texture});
MAGNUM_VERIFY_NO_ERROR();
}
#ifndef MAGNUM_TARGET_GLES

Loading…
Cancel
Save