diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index deba97934..78b4f62ea 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -431,9 +431,9 @@ OpenGL function | Matching API @def_gl{MAX_COMPUTE_SHARED_MEMORY_SIZE} | @ref AbstractShaderProgram::maxComputeSharedMemorySize() @def_gl_extension{MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS,ARB,compute_variable_group_size} | | @def_gl_extension{MAX_COMPUTE_VARIABLE_GROUP_SIZE,ARB,compute_variable_group_size} | | -@def_gl{MAX_COMPUTE_WORK_GROUP_COUNT} | | +@def_gl{MAX_COMPUTE_WORK_GROUP_COUNT} | @ref AbstractShaderProgram::maxComputeWorkGroupCount() @def_gl{MAX_COMPUTE_WORK_GROUP_INVOCATIONS} | @ref AbstractShaderProgram::maxComputeWorkGroupInvocations() -@def_gl{MAX_COMPUTE_WORK_GROUP_SIZE} | | +@def_gl{MAX_COMPUTE_WORK_GROUP_SIZE} | @ref AbstractShaderProgram::maxComputeWorkGroupSize() @def_gl{MAX_CULL_DISTANCES} | | @def_gl{MAX_DEBUG_LOGGED_MESSAGES} | @ref DebugOutput::maxLoggedMessages() @def_gl{MAX_DEBUG_MESSAGE_LENGTH} | @ref DebugOutput::maxMessageLength() diff --git a/src/Magnum/AbstractShaderProgram.cpp b/src/Magnum/AbstractShaderProgram.cpp index 933c1b47e..4ff1b1cd2 100644 --- a/src/Magnum/AbstractShaderProgram.cpp +++ b/src/Magnum/AbstractShaderProgram.cpp @@ -108,6 +108,44 @@ Int AbstractShaderProgram::maxComputeWorkGroupInvocations() { return value; } +Vector3i AbstractShaderProgram::maxComputeWorkGroupCount() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current().isExtensionSupported()) + #else + if(!Context::current().isVersionSupported(Version::GLES310)) + #endif + return {}; + + Vector3i& value = Context::current().state().shaderProgram->maxComputeWorkGroupCount; + + if(value.isZero()) { + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &value.x()); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &value.y()); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &value.z()); + } + + return value; +} + +Vector3i AbstractShaderProgram::maxComputeWorkGroupSize() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current().isExtensionSupported()) + #else + if(!Context::current().isVersionSupported(Version::GLES310)) + #endif + return {}; + + Vector3i& value = Context::current().state().shaderProgram->maxComputeWorkGroupSize; + + if(value.isZero()) { + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &value.x()); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &value.y()); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &value.z()); + } + + return value; +} + Int AbstractShaderProgram::maxImageUnits() { #ifndef MAGNUM_TARGET_GLES if(!Context::current().isExtensionSupported()) diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index 6d75f1783..4769aa735 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -539,7 +539,31 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { */ static Int maxComputeWorkGroupInvocations(); - /** @todo MAX_COMPUTE_WORK_GROUP_COUNT, MAX_COMPUTE_WORK_GROUP_SIZE */ + /** + * @brief Max supported compute work group count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If neither extension @extension{ARB,compute_shader} + * (part of OpenGL 4.3) nor OpenGL ES 3.1 is available, returns zero + * vector. + * @see @fn_gl{Get} with @def_gl{MAX_COMPUTE_WORK_GROUP_COUNT} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles Compute shaders are not available in WebGL. + */ + static Vector3i maxComputeWorkGroupCount(); + + /** + * @brief Max supported compute work group size + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If neither extension @extension{ARB,compute_shader} + * (part of OpenGL 4.3) nor OpenGL ES 3.1 is available, returns zero + * vector. + * @see @fn_gl{Get} with @def_gl{MAX_COMPUTE_WORK_GROUP_SIZE} + * @requires_gles30 Not defined in OpenGL ES 2.0. + * @requires_gles Compute shaders are not available in WebGL. + */ + static Vector3i maxComputeWorkGroupSize(); /** * @brief Max supported image unit count diff --git a/src/Magnum/Implementation/ShaderProgramState.h b/src/Magnum/Implementation/ShaderProgramState.h index 9c0ceba56..cc3c3cb7d 100644 --- a/src/Magnum/Implementation/ShaderProgramState.h +++ b/src/Magnum/Implementation/ShaderProgramState.h @@ -30,6 +30,7 @@ #include "Magnum/Magnum.h" #include "Magnum/OpenGL.h" +#include "Magnum/Math/Vector3.h" #ifdef _MSC_VER /* Otherwise the member function pointers will have different size based on @@ -101,6 +102,8 @@ struct ShaderProgramState { maxImageUnits, maxCombinedShaderOutputResources, maxUniformLocations; + Vector3i maxComputeWorkGroupCount, + maxComputeWorkGroupSize; #endif GLint minTexelOffset, maxTexelOffset, diff --git a/src/Magnum/Platform/magnum-info.cpp b/src/Magnum/Platform/magnum-info.cpp index c3c8428af..f75c13093 100644 --- a/src/Magnum/Platform/magnum-info.cpp +++ b/src/Magnum/Platform/magnum-info.cpp @@ -310,7 +310,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat /* Limits and implementation-defined values */ #define _h(val) Debug() << "\n " << Extensions::GL::val::string() + std::string(":"); #define _l(val) Debug() << " " << #val << (sizeof(#val) > 64 ? "\n" + std::string(68, ' ') : std::string(64 - sizeof(#val), ' ')) << val; - #define _lvec(val) Debug() << " " << #val << (sizeof(#val) > 48 ? "\n" + std::string(52, ' ') : std::string(48 - sizeof(#val), ' ')) << val; + #define _lvec(val) Debug() << " " << #val << (sizeof(#val) > 42 ? "\n" + std::string(46, ' ') : std::string(42 - sizeof(#val), ' ')) << val; Debug() << "Limits and implementation-defined values:"; _lvec(AbstractFramebuffer::maxViewportSize()) @@ -374,6 +374,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat _l(AbstractShaderProgram::maxComputeSharedMemorySize()) _l(AbstractShaderProgram::maxComputeWorkGroupInvocations()) + _lvec(AbstractShaderProgram::maxComputeWorkGroupCount()) + _lvec(AbstractShaderProgram::maxComputeWorkGroupSize()) } #ifndef MAGNUM_TARGET_GLES