Browse Source

Texture-related limit queries.

Renamed AbstractTexture::maxSupportedLayerCount() to maxLayers(),
which is in fact alias to Shader::maxCombinedTextureImageUnits(). Also
renamed Samples::maxSupportedAnisotropy() to maxAnisotropy(). It now
has slightly confusing naming, will fix that later. Both
original functions are now alias to new ones to retain source
compatibility, will be removed in future releases.

Also printing the values in magnum-info.
pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
6ee2745503
  1. 55
      src/AbstractTexture.cpp
  2. 72
      src/AbstractTexture.h
  3. 6
      src/Implementation/TextureState.cpp
  4. 8
      src/Implementation/TextureState.h
  5. 13
      src/Platform/magnum-info.cpp
  6. 4
      src/Sampler.cpp
  7. 11
      src/Sampler.h
  8. 2
      src/Texture.h

55
src/AbstractTexture.cpp

@ -30,6 +30,7 @@
#include "Extensions.h"
#include "Image.h"
#include "ImageFormat.h"
#include "Shader.h"
#include "TextureFormat.h"
#include "Implementation/State.h"
#include "Implementation/TextureState.h"
@ -80,10 +81,49 @@ AbstractTexture::SubImage3DImplementation AbstractTexture::subImage3DImplementat
AbstractTexture::InvalidateImageImplementation AbstractTexture::invalidateImageImplementation = &AbstractTexture::invalidateImageImplementationNoOp;
AbstractTexture::InvalidateSubImageImplementation AbstractTexture::invalidateSubImageImplementation = &AbstractTexture::invalidateSubImageImplementationNoOp;
Int AbstractTexture::maxSupportedLayerCount() {
return Context::current()->state().texture->maxSupportedLayerCount;
Int AbstractTexture::maxLayers() { return Shader::maxCombinedTextureImageUnits(); }
#ifndef MAGNUM_TARGET_GLES
Int AbstractTexture::maxColorSamples() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
return 0;
GLint& value = Context::current()->state().texture->maxColorSamples;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &value);
return value;
}
Int AbstractTexture::maxDepthSamples() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
return 0;
GLint& value = Context::current()->state().texture->maxDepthSamples;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &value);
return value;
}
Int AbstractTexture::maxIntegerSamples() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
return 0;
GLint& value = Context::current()->state().texture->maxIntegerSamples;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &value);
return value;
}
#endif
void AbstractTexture::destroy() {
/* Moved out */
if(!_id) return;
@ -183,7 +223,7 @@ void AbstractTexture::bindInternal() {
return;
/* Set internal layer as active if not already */
const GLint internalLayer = textureState->maxSupportedLayerCount-1;
const GLint internalLayer = maxLayers()-1;
if(textureState->currentLayer != internalLayer)
glActiveTexture(GL_TEXTURE0 + (textureState->currentLayer = internalLayer));
@ -193,13 +233,6 @@ void AbstractTexture::bindInternal() {
}
void AbstractTexture::initializeContextBasedFunctionality(Context& context) {
Implementation::TextureState* const textureState = context.state().texture;
GLint& value = textureState->maxSupportedLayerCount;
/* Get the value and resize bindings array */
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value);
textureState->bindings.resize(value);
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
Debug() << "AbstractTexture: using" << Extensions::GL::EXT::direct_state_access::string() << "features";
@ -246,6 +279,8 @@ void AbstractTexture::initializeContextBasedFunctionality(Context& context) {
storage3DImplementation = &AbstractTexture::storageImplementationDefault;
}
}
#else
static_cast<void>(context);
#endif
}

72
src/AbstractTexture.h

@ -48,9 +48,9 @@ information and usage examples.
The engine tracks currently bound textures in all available layers to avoid
unnecessary calls to @fn_gl{ActiveTexture} and @fn_gl{BindTexture}. %Texture
configuration functions use dedicated highest available texture layer to not
affect active bindings in user layers. %Texture limits (such as
maxSupportedLayerCount()) are cached, so repeated queries don't result in
repeated @fn_gl{Get} calls.
affect active bindings in user layers. %Texture limits and
implementation-defined values (such as @ref maxColorSamples()) are cached, so
repeated queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{EXT,direct_state_access} is available, bind() uses DSA
function to avoid unnecessary calls to @fn_gl{ActiveTexture}. Also all texture
@ -91,6 +91,10 @@ do nothing.
@todo Move constructor/assignment - how to avoid creation of empty texture and
then deleting it immediately?
@todo ES2 - proper support for pixel unpack buffer when extension is in headers
@todo `GL_MAX_3D_TEXTURE_SIZE`, `GL_MAX_ARRAY_TEXTURE_LAYERS`, `GL_MAX_CUBE_MAP_TEXTURE_SIZE`, `GL_MAX_RECTANGLE_TEXTURE_SIZE`, `GL_MAX_TEXTURE_SIZE`, `GL_MAX_TEXTURE_BUFFER_SIZE` enable them only where it makes sense?
@todo `GL_MAX_TEXTURE_LOD_BIAS` when `TEXTURE_LOD_BIAS` is implemented
@todo `GL_NUM_COMPRESSED_TEXTURE_FORMATS` when compressed textures are implemented
@todo `GL_MAX_SAMPLE_MASK_WORDS` when @extension{ARB,texture_multisample} is done
*/
class MAGNUM_EXPORT AbstractTexture {
friend class Context;
@ -100,12 +104,53 @@ class MAGNUM_EXPORT AbstractTexture {
* @brief Max supported layer count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls.
* @see @ref AbstractShaderProgram-subclassing, bind(Int),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_TEXTURE_IMAGE_UNITS},
* @fn_gl{ActiveTexture}
* OpenGL calls. This function is in fact alias to
* @ref Shader::maxCombinedTextureImageUnits().
* @see @ref bind(Int)
*/
static Int maxSupportedLayerCount();
static Int maxLayers();
/**
* @copybrief maxLayers()
* @deprecated Use @ref Magnum::AbstractTexture::maxLayers() "maxLayers()"
* instead.
*/
static Int maxSupportedLayerCount() { return maxLayers(); }
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Max supported color sample count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,texture_multisample} is
* not available, returns `0`.
* @see @fn_gl{Get} with @def_gl{MAX_COLOR_TEXTURE_SAMPLES}
* @requires_gl Multisample textures are not available in OpenGL ES.
*/
static Int maxColorSamples();
/**
* @brief Max supported depth sample count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,texture_multisample} is
* not available, returns `0`.
* @see @fn_gl{Get} with @def_gl{MAX_DEPTH_TEXTURE_SAMPLES}
* @requires_gl Multisample textures are not available in OpenGL ES.
*/
static Int maxDepthSamples();
/**
* @brief Max supported integer sample count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,texture_multisample} is
* not available, returns `0`.
* @see @fn_gl{Get} with @def_gl{MAX_INTEGER_SAMPLES}
* @requires_gl Multisample textures are not available in OpenGL ES.
*/
static Int maxIntegerSamples();
#endif
/** @brief Copying is not allowed */
AbstractTexture(const AbstractTexture&) = delete;
@ -126,11 +171,10 @@ class MAGNUM_EXPORT AbstractTexture {
* @brief Bind texture for rendering
*
* Sets current texture as active in given layer. The layer must be
* between 0 and maxSupportedLayerCount(). Note that only one texture
* can be bound to given layer. If @extension{EXT,direct_state_access}
* is not available, the layer is made active before binding the
* texture.
* @see @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* between 0 and @ref maxLayers(). Note that only one texture can be
* bound to given layer. If @extension{EXT,direct_state_access} is not
* available, the layer is made active before binding the texture.
* @see @ref maxLayers(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/
void bind(Int layer);
@ -205,7 +249,7 @@ class MAGNUM_EXPORT AbstractTexture {
* greater than `1.0f` for anisotropic filtering. If
* @extension{EXT,direct_state_access} is not available, the texture
* is bound to some layer before the operation.
* @see maxSupportedAnisotropy(), @fn_gl{ActiveTexture},
* @see @ref Sampler::maxAnisotropy(), @fn_gl{ActiveTexture},
* @fn_gl{BindTexture} and @fn_gl{TexParameter} or
* @fn_gl_extension{TextureParameter,EXT,direct_state_access} with
* @def_gl{TEXTURE_MAX_ANISOTROPY_EXT}

6
src/Implementation/TextureState.cpp

@ -26,7 +26,11 @@
namespace Magnum { namespace Implementation {
TextureState::TextureState(): maxSupportedLayerCount(0), maxSupportedAnisotropy(0.0f), currentLayer(0) {}
TextureState::TextureState(): maxAnisotropy(0.0f), currentLayer(0)
#ifndef MAGNUM_TARGET_GLES
, maxColorSamples(0), maxDepthSamples(0), maxIntegerSamples(0)
#endif
{}
TextureState::~TextureState() = default;

8
src/Implementation/TextureState.h

@ -34,9 +34,13 @@ struct TextureState {
explicit TextureState();
~TextureState();
GLint maxSupportedLayerCount;
GLfloat maxSupportedAnisotropy;
GLfloat maxAnisotropy;
GLint currentLayer;
#ifndef MAGNUM_TARGET_GLES
GLint maxColorSamples,
maxDepthSamples,
maxIntegerSamples;
#endif
std::vector<GLuint> bindings;
};

13
src/Platform/magnum-info.cpp

@ -214,6 +214,11 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
_l(AbstractShaderProgram::maxUniformLocations())
#endif
_l(AbstractShaderProgram::maxVertexAttributes())
#ifndef MAGNUM_TARGET_GLES
_l(AbstractTexture::maxColorSamples())
_l(AbstractTexture::maxDepthSamples())
_l(AbstractTexture::maxIntegerSamples())
#endif
#ifndef MAGNUM_TARGET_GLES
if(c->isExtensionSupported<Extensions::GL::ARB::blend_func_extended>()) {
@ -329,6 +334,14 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
}
#endif
#ifndef MAGNUM_TARGET_GLES3
if(c->isExtensionSupported<Extensions::GL::EXT::texture_filter_anisotropic>()) {
_h(EXT::texture_filter_anisotropic)
_l(Sampler::maxAnisotropy())
}
#endif
#undef _l
#undef _h
}

4
src/Sampler.cpp

@ -46,8 +46,8 @@ static_assert((filter_or(Nearest, Base) == GL_NEAREST) &&
#undef filter_or
#ifndef MAGNUM_TARGET_GLES3
Float Sampler::maxSupportedAnisotropy() {
GLfloat& value = Context::current()->state().texture->maxSupportedAnisotropy;
Float Sampler::maxAnisotropy() {
GLfloat& value = Context::current()->state().texture->maxAnisotropy;
/** @todo Re-enable when extension header is available */
#ifndef MAGNUM_TARGET_GLES

11
src/Sampler.h

@ -39,7 +39,7 @@ namespace Magnum {
@see Texture, CubeMapTexture, CubeMapTextureArray
*/
class Sampler {
class MAGNUM_EXPORT Sampler {
public:
/**
* @brief %Texture filtering
@ -144,7 +144,14 @@ class Sampler {
* @requires_extension %Extension @extension{EXT,texture_filter_anisotropic}
* @requires_es_extension %Extension @es_extension2{EXT,texture_filter_anisotropic,texture_filter_anisotropic}
*/
static Float maxSupportedAnisotropy();
static Float maxAnisotropy();
/**
* @copybrief maxAnisotropy()
* @deprecated Use @ref Magnum::Shader::maxAnisotropy() "maxAnisotropy()"
* instead.
*/
static Float maxSupportedAnisotropy() { return maxAnisotropy(); }
#endif
};

2
src/Texture.h

@ -52,7 +52,7 @@ Texture2D texture;
texture.setMagnificationFilter(Sampler::Filter::Linear)
.setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear)
.setWrapping(Sampler::Wrapping::ClampToEdge)
.setMaxAnisotropy(Sampler::maxSupportedAnisotropy())
.setMaxAnisotropy(Sampler::maxAnisotropy())
.setStorage(Math::log2(4096)+1, TextureFormat::RGBA8, {4096, 4096})
.setSubImage(0, {}, &image)
.generateMipmap();

Loading…
Cancel
Save