From 6ee2745503bf056185f111d6faeb1f2491210af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 6 Oct 2013 00:08:39 +0200 Subject: [PATCH] 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. --- src/AbstractTexture.cpp | 55 ++++++++++++++++++---- src/AbstractTexture.h | 72 +++++++++++++++++++++++------ src/Implementation/TextureState.cpp | 6 ++- src/Implementation/TextureState.h | 8 +++- src/Platform/magnum-info.cpp | 13 ++++++ src/Sampler.cpp | 4 +- src/Sampler.h | 11 ++++- src/Texture.h | 2 +- 8 files changed, 139 insertions(+), 32 deletions(-) diff --git a/src/AbstractTexture.cpp b/src/AbstractTexture.cpp index 481679606..63a8d3ccb 100644 --- a/src/AbstractTexture.cpp +++ b/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()) + 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()) + 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()) + 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()) { 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(context); #endif } diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 6e505dc83..1fd395ae5 100644 --- a/src/AbstractTexture.h +++ b/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} diff --git a/src/Implementation/TextureState.cpp b/src/Implementation/TextureState.cpp index 7524d218b..7c08ebceb 100644 --- a/src/Implementation/TextureState.cpp +++ b/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; diff --git a/src/Implementation/TextureState.h b/src/Implementation/TextureState.h index 2e53176c1..91875bc9e 100644 --- a/src/Implementation/TextureState.h +++ b/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 bindings; }; diff --git a/src/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index 528f56e65..0b5ae7435 100644 --- a/src/Platform/magnum-info.cpp +++ b/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()) { @@ -329,6 +334,14 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat } #endif + #ifndef MAGNUM_TARGET_GLES3 + if(c->isExtensionSupported()) { + _h(EXT::texture_filter_anisotropic) + + _l(Sampler::maxAnisotropy()) + } + #endif + #undef _l #undef _h } diff --git a/src/Sampler.cpp b/src/Sampler.cpp index 2d65ffe11..4aa722741 100644 --- a/src/Sampler.cpp +++ b/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 diff --git a/src/Sampler.h b/src/Sampler.h index 54780efd4..1991ae216 100644 --- a/src/Sampler.h +++ b/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 }; diff --git a/src/Texture.h b/src/Texture.h index 82251d76c..b843090b4 100644 --- a/src/Texture.h +++ b/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();