From 4a983566e638cd43064ae8ce71d29fb3a0e279f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 5 Oct 2013 23:35:07 +0200 Subject: [PATCH] Buffer-related limit queries. Also printing the values in magnum-info. --- src/Buffer.cpp | 63 +++++++++++++++++++++++++ src/Buffer.h | 79 ++++++++++++++++++++++++++++++-- src/Implementation/BufferState.h | 21 ++++++++- src/Platform/magnum-info.cpp | 5 ++ 4 files changed, 163 insertions(+), 5 deletions(-) diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 5286ac42f..507f080da 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -78,6 +78,69 @@ void Buffer::initializeContextBasedFunctionality(Context& context) { #endif } +#ifndef MAGNUM_TARGET_GLES +Int Buffer::minMapAlignment() { + GLint& value = Context::current()->state().buffer->minMapAlignment; + + if(value == 0) + glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &value); + + return value; +} + +Int Buffer::maxAtomicCounterBindings() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().buffer->maxAtomicCounterBindings; + + if(value == 0) + glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &value); + + return value; +} + +Int Buffer::maxShaderStorageBindings() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().buffer->maxShaderStorageBindings; + + if(value == 0) + glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &value); + + return value; +} + +Int Buffer::shaderStorageOffsetAlignment() { + if(!Context::current()->isExtensionSupported()) + return 0; + + GLint& value = Context::current()->state().buffer->shaderStorageOffsetAlignment; + + if(value == 0) + glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &value); + + return value; +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +Int Buffer::maxUniformBindings() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + return 0; + #endif + + GLint& value = Context::current()->state().buffer->maxUniformBindings; + + if(value == 0) + glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &value); + + return value; +} +#endif + Buffer::Buffer(Buffer::Target targetHint): _targetHint(targetHint) #ifdef CORRADE_TARGET_NACL , _mappedBuffer(nullptr) diff --git a/src/Buffer.h b/src/Buffer.h index 4e6a516be..3900f986f 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -106,7 +106,9 @@ The engine tracks currently bound buffers to avoid unnecessary calls to @fn_gl{BindBuffer}. If the buffer is already bound to some target, functions copy(), setData(), setSubData(), map(), flushMappedRange() and unmap() use that target instead of binding the buffer to some specific target. You can -also use setTargetHint() to possibly reduce unnecessary rebinding. +also use setTargetHint() to possibly reduce unnecessary rebinding. %Buffer +limits and implementation-defined values (such as @ref maxVertexAttributeBindings()) +are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. If extension @extension{EXT,direct_state_access} is available, functions copy(), setData(), setSubData(), map(), flushMappedRange() and unmap() use DSA @@ -428,6 +430,73 @@ class MAGNUM_EXPORT Buffer { */ typedef Containers::EnumSet MapFlags; + #ifndef MAGNUM_TARGET_GLES + /** + * @brief Minimal supported mapping alignment + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. + * @see @ref map(), @fn_gl{Get} with @def_gl{MIN_MAP_BUFFER_ALIGNMENT} + * @requires_gl No minimal value is specified for OpenGL ES. + */ + static Int minMapAlignment(); + + /** + * @brief Max supported atomic counter buffer binding count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{ARB,shader_atomic_counters} is + * not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_ATOMIC_COUNTER_BUFFER_BINDINGS} + * @requires_gl Atomic counters are not available in OpenGL ES. + */ + static Int maxAtomicCounterBindings(); + + /** + * @brief Max supported shader storage buffer binding count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{ARB,shader_storage_buffer_object} + * is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_SHADER_STORAGE_BUFFER_BINDINGS} + * @requires_gl Atomic counters are not available in OpenGL ES. + */ + static Int maxShaderStorageBindings(); + + /** + * @brief Alignment of shader storage buffer binding offset + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{ARB,shader_storage_buffer_object} + * is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT} + * @requires_gl Atomic counters are not available in OpenGL ES. + */ + static Int shaderStorageOffsetAlignment(); + #endif + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Max supported uniform buffer binding count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If extension @extension{ARB,uniform_buffer_object} + * is not available, returns `0`. + * @see @fn_gl{Get} with @def_gl{MAX_UNIFORM_BUFFER_BINDINGS} + * @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0. + */ + static Int maxUniformBindings(); + #endif + + /** + * @brief Max supported vertex buffer binding count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. + * @see @fn_gl{Get} with @def_gl{MAX_VERTEX_ATTRIB_BINDINGS} + */ + static Int maxVertexAttributeBindings(); + /** * @brief Unbind any buffer from given target * @param target %Target @@ -724,8 +793,9 @@ class MAGNUM_EXPORT Buffer { * before the operation. * @deprecated Prefer to use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * instead, as it has more complete set of features. - * @see unmap(), setTargetHint(), @fn_gl{BindBuffer} and @fn_gl{MapBuffer} - * or @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access} + * @see @ref minMapAlignment(), @ref unmap(), @ref setTargetHint(), + * @fn_gl{BindBuffer} and @fn_gl{MapBuffer} or + * @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access} * @requires_es_extension %Extension @es_extension{OES,mapbuffer} in * OpenGL ES 2.0, use @ref Magnum::Buffer::map(GLintptr, GLsizeiptr, MapFlags) "map(GLintptr, GLsizeiptr, MapFlags)" * in OpenGL ES 3.0 instead. @@ -767,7 +837,8 @@ class MAGNUM_EXPORT Buffer { * If @extension{EXT,direct_state_access} is not available and the * buffer is not already bound somewhere, it is bound to hinted target * before the operation. - * @see flushMappedRange(), unmap(), map(MapAccess), setTargetHint(), @fn_gl{BindBuffer} + * @see @ref minMapAlignment(), @ref flushMappedRange(), @ref unmap(), + * @ref map(MapAccess), @ref setTargetHint(), @fn_gl{BindBuffer} * and @fn_gl{MapBufferRange} or @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access} * @requires_gl30 %Extension @extension{ARB,map_buffer_range} * @requires_gles30 %Extension @es_extension{EXT,map_buffer_range} diff --git a/src/Implementation/BufferState.h b/src/Implementation/BufferState.h index 5c69f7201..6ca93515e 100644 --- a/src/Implementation/BufferState.h +++ b/src/Implementation/BufferState.h @@ -43,10 +43,29 @@ struct BufferState { static std::size_t indexForTarget(Buffer::Target target); static const Buffer::Target targetForIndex[TargetCount-1]; - constexpr BufferState(): bindings() {} + constexpr BufferState(): bindings() + #ifndef MAGNUM_TARGET_GLES2 + #ifndef MAGNUM_TARGET_GLES + , minMapAlignment(0), maxAtomicCounterBindings(0), maxShaderStorageBindings(0), shaderStorageOffsetAlignment(0) + #endif + , maxUniformBindings(0) + #endif + {} /* Currently bound buffer for all targets */ GLuint bindings[TargetCount]; + + /* Limits */ + #ifndef MAGNUM_TARGET_GLES2 + GLint + #ifndef MAGNUM_TARGET_GLES + minMapAlignment, + maxAtomicCounterBindings, + maxShaderStorageBindings, + shaderStorageOffsetAlignment, + #endif + maxUniformBindings; + #endif }; }} diff --git a/src/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index 8e6eca7d7..528f56e65 100644 --- a/src/Platform/magnum-info.cpp +++ b/src/Platform/magnum-info.cpp @@ -30,6 +30,7 @@ #endif #include "AbstractShaderProgram.h" +#include "Buffer.h" #include "Context.h" #include "Extensions.h" #include "Framebuffer.h" @@ -239,6 +240,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat if(c->isExtensionSupported()) { _h(ARB::shader_atomic_counters) + _l(Buffer::maxAtomicCounterBindings()) _l(Shader::maxAtomicCounterBuffers(Shader::Type::Vertex)) _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationControl)) _l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationEvaluation)) @@ -288,6 +290,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat if(c->isExtensionSupported()) { _h(ARB::tessellation_shader) + _l(Buffer::shaderStorageOffsetAlignment()) + _l(Buffer::maxShaderStorageBindings()) _l(Shader::maxTessellationControlInputComponents()) _l(Shader::maxTessellationControlOutputComponents()) _l(Shader::maxTessellationControlTotalOutputComponents()) @@ -319,6 +323,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat if(c->isExtensionSupported()) { _h(EXT::gpu_shader4) + _l(Buffer::maxUniformBindings()) _l(AbstractShaderProgram::minTexelOffset()) _l(AbstractShaderProgram::maxTexelOffset()) }