Browse Source

Shader-related limit queries.

Renamed AbstractShaderProgram::maxSupportedVertexAttributeCount() to
maxVertexAttributes(), the old function is now an alias to retain
source compatibility, will be removed in future release.

Also printing the values in magnum-info.
pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
a040b358ef
  1. 151
      src/AbstractShaderProgram.cpp
  2. 157
      src/AbstractShaderProgram.h
  3. 26
      src/Implementation/ShaderProgramState.h
  4. 92
      src/Implementation/ShaderState.h
  5. 15
      src/Implementation/State.cpp
  6. 2
      src/Implementation/State.h
  7. 139
      src/Platform/magnum-info.cpp
  8. 476
      src/Shader.cpp
  9. 345
      src/Shader.h

151
src/AbstractShaderProgram.cpp

@ -76,8 +76,8 @@ AbstractShaderProgram::UniformMatrix3x4dvImplementation AbstractShaderProgram::u
AbstractShaderProgram::UniformMatrix4x3dvImplementation AbstractShaderProgram::uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault;
#endif
Int AbstractShaderProgram::maxSupportedVertexAttributeCount() {
GLint& value = Context::current()->state().shaderProgram->maxSupportedVertexAttributeCount;
Int AbstractShaderProgram::maxVertexAttributes() {
GLint& value = Context::current()->state().shaderProgram->maxVertexAttributes;
/* Get the value, if not already cached */
if(value == 0)
@ -86,6 +86,153 @@ Int AbstractShaderProgram::maxSupportedVertexAttributeCount() {
return value;
}
#ifndef MAGNUM_TARGET_GLES
Int AbstractShaderProgram::maxAtomicCounterBufferSize() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxAtomicCounterBufferSize;
if(value == 0)
glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, &value);
return value;
}
Int AbstractShaderProgram::maxComputeSharedMemorySize() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::compute_shader>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxComputeSharedMemorySize;
if(value == 0)
glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &value);
return value;
}
Int AbstractShaderProgram::maxComputeWorkGroupInvocations() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::compute_shader>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxComputeWorkGroupInvocations;
/** @todo Fix when glLoadGen has `GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS` */
if(value == 0)
glGetIntegerv(/*GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS*/0x90EB, &value);
return value;
}
Int AbstractShaderProgram::maxImageUnits() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxImageUnits;
if(value == 0)
glGetIntegerv(GL_MAX_IMAGE_UNITS, &value);
return value;
}
Int AbstractShaderProgram::maxImageSamples() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxImageSamples;
if(value == 0)
glGetIntegerv(GL_MAX_IMAGE_SAMPLES, &value);
return value;
}
Int AbstractShaderProgram::maxCombinedShaderOutputResources() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_storage_buffer_object>() || !Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxCombinedShaderOutputResources;
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, &value);
return value;
}
Long AbstractShaderProgram::maxShaderStorageBlockSize() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_storage_buffer_object>())
return 0;
GLint64& value = Context::current()->state().shaderProgram->maxShaderStorageBlockSize;
if(value == 0)
glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &value);
return value;
}
#endif
#ifndef MAGNUM_TARGET_GLES2
Int AbstractShaderProgram::maxUniformBlockSize() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>())
return 0;
#endif
GLint& value = Context::current()->state().shaderProgram->maxUniformBlockSize;
if(value == 0)
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &value);
return value;
}
#endif
#ifndef MAGNUM_TARGET_GLES
Int AbstractShaderProgram::maxUniformLocations() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_uniform_location>())
return 0;
GLint& value = Context::current()->state().shaderProgram->maxUniformLocations;
if(value == 0)
glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS, &value);
return value;
}
#endif
#ifndef MAGNUM_TARGET_GLES2
Int AbstractShaderProgram::minTexelOffset() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::gpu_shader4>())
return 0;
#endif
GLint& value = Context::current()->state().shaderProgram->minTexelOffset;
if(value == 0)
glGetIntegerv(GL_MIN_PROGRAM_TEXEL_OFFSET, &value);
return value;
}
Int AbstractShaderProgram::maxTexelOffset() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::gpu_shader4>())
return 0;
#endif
GLint& value = Context::current()->state().shaderProgram->maxTexelOffset;
if(value == 0)
glGetIntegerv(GL_MAX_PROGRAM_TEXEL_OFFSET, &value);
return value;
}
#endif
AbstractShaderProgram::AbstractShaderProgram(): _id(glCreateProgram()) {}
AbstractShaderProgram::AbstractShaderProgram(AbstractShaderProgram&& other) noexcept: _id(other._id) {

157
src/AbstractShaderProgram.h

@ -149,6 +149,7 @@ bindFragmentDataLocationIndexed(NormalOutput, 1, "normal");
// Link...
@endcode
@see @ref Mesh::maxVertexAttributes(), @ref AbstractFramebuffer::maxDrawBuffers()
@requires_gl30 %Extension @extension{EXT,gpu_shader4} for using
bindFragmentDataLocation().
@requires_gl33 %Extension @extension{ARB,blend_func_extended} for using
@ -180,6 +181,7 @@ Int transformationUniform = uniformLocation("transformation");
Int projectionUniform = uniformLocation("projection");
@endcode
@see @ref maxUniformLocations()
@requires_gl43 %Extension @extension{ARB,explicit_uniform_location} for
explicit uniform location instead of using uniformLocation().
@requires_gl Explicit uniform location is not supported in OpenGL ES. Use
@ -203,6 +205,7 @@ setUniform(DiffuseTextureUniform, DiffuseTextureLayer);
setUniform(SpecularTextureUniform, SpecularTextureLayer);
@endcode
@see @ref Shader::maxTextureImageUnits()
@requires_gl42 %Extension @extension{ARB,shading_language_420pack} for explicit
texture layer binding instead of using setUniform(Int, Int).
@requires_gl Explicit texture layer binding is not supported in OpenGL ES. Use
@ -272,7 +275,7 @@ See @ref types for more information, only types with GLSL equivalent can be used
@section AbstractShaderProgram-performance-optimization Performance optimizations
The engine tracks currently used shader program to avoid unnecessary calls to
@fn_gl{UseProgram}. %Shader limits (such as maxSupportedVertexAttributeCount())
@fn_gl{UseProgram}. %Shader limits (such as @ref maxVertexAttributes())
are cached, so repeated queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{ARB,separate_shader_objects} or
@ -287,6 +290,7 @@ comes in handy.
@todo Compiling and linking more than one shader in parallel, then checking
status, should be faster -- https://twitter.com/g_truc/status/352778836657700866
@todo `GL_NUM_{PROGRAM,SHADER}_BINARY_FORMATS` + `GL_{PROGRAM,SHADER}_BINARY_FORMATS` (vector), (@extension{ARB,ES2_compatibility})
*/
class MAGNUM_EXPORT AbstractShaderProgram {
friend class Context;
@ -299,9 +303,152 @@ class MAGNUM_EXPORT AbstractShaderProgram {
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls.
* @see Attribute, @fn_gl{Get} with @def_gl{MAX_VERTEX_ATTRIBS}
* @see @ref Mesh::maxVertexAttributes(),
* @ref AbstractShaderProgram::Attribute, @fn_gl{Get} with
* @def_gl{MAX_VERTEX_ATTRIBS}
*/
static Int maxSupportedVertexAttributeCount();
static Int maxVertexAttributes();
/**
* @copydoc maxVertexAttributes()
* @deprecated Use @ref Magnum::AbstractShaderProgram::maxVertexAttributes() "maxVertexAttributes()"
* instead.
*/
static Int maxSupportedVertexAttributeCount() { return maxVertexAttributes(); }
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Max supported atomic counter buffer size
*
* 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`.
* @requires_gl Atomic counters are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_ATOMIC_COUNTER_BUFFER_SIZE}
*/
static Int maxAtomicCounterBufferSize();
/**
* @brief Max supported compute shared memory size
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,compute_shader} is not
* available, returns `0`.
* @requires_gl Compute shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_COMPUTE_SHARED_MEMORY_SIZE}
*/
static Int maxComputeSharedMemorySize();
/**
* @brief Max supported compute work group invocation count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,compute_shader} is not
* available, returns `0`.
* @requires_gl Compute shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_COMPUTE_WORK_GROUP_INVOCATIONS}
*/
static Int maxComputeWorkGroupInvocations();
/** @todo MAX_COMPUTE_WORK_GROUP_COUNT, MAX_COMPUTE_WORK_GROUP_SIZE */
/**
* @brief Max supported image unit count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_image_load_store}
* is not available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_IMAGE_UNITS}
*/
static Int maxImageUnits();
/**
* @brief Max supported image sample count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_image_load_store}
* is not available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_IMAGE_SAMPLES}
*/
static Int maxImageSamples();
/**
* @brief Max supported combined shader output resource count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If neither @extension{ARB,shader_image_load_store}
* nor @extension{ARB,shader_storage_buffer_object} extension is
* available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_COMBINED_SHADER_OUTPUT_RESOURCES}
*/
static Int maxCombinedShaderOutputResources();
/**
* @brief Max supported shader storage block size
*
* 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`.
* @requires_gl Shader storage is not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_SHADER_STORAGE_BLOCK_SIZE}
*/
static Long maxShaderStorageBlockSize();
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Max supported uniform block size
*
* 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`.
* @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
* @see @fn_gl{Get} with @def_gl{MAX_UNIFORM_BLOCK_SIZE}
*/
static Int maxUniformBlockSize();
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Max supported explicit uniform location count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,explicit_uniform_location}
* is not available, returns `0`.
* @requires_gl Explicit uniform location is not supported in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_UNIFORM_LOCATIONS}
*/
static Int maxUniformLocations();
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Min supported program texel offset
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{EXT,gpu_shader4} is not
* available, returns `0`.
* @requires_gles30 Texture lookup with offset is not available in
* OpenGL ES 2.0.
* @see @fn_gl{Get} with @def_gl{MIN_PROGRAM_TEXEL_OFFSET}
*/
static Int minTexelOffset();
/**
* @brief Max supported program texel offset
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{EXT,gpu_shader4} is not
* available, returns `0`.
* @requires_gles30 Texture lookup with offset is not available in
* OpenGL ES 2.0.
* @see @fn_gl{Get} with @def_gl{MAX_PROGRAM_TEXEL_OFFSET}
*/
static Int maxTexelOffset();
#endif
/**
* @brief Constructor
@ -947,8 +1094,8 @@ class MAGNUM_EXPORT AbstractShaderProgram {
@brief Base struct for attribute location and type
Template parameter @p location is vertex attribute location, number between `0`
and maxSupportedVertexAttributeCount(). To ensure compatibility, you should
always have vertex attribute with location `0`.
and @ref maxVertexAttributes(). To ensure compatibility, you should always have
vertex attribute with location `0`.
Template parameter @p T is the type which is used for shader attribute, e.g.
@ref Vector4i for `ivec4`. DataType is type of passed data when adding vertex

26
src/Implementation/ShaderProgramState.h

@ -29,11 +29,33 @@
namespace Magnum { namespace Implementation {
struct ShaderProgramState {
constexpr ShaderProgramState(): current(0), maxSupportedVertexAttributeCount(0) {}
constexpr ShaderProgramState(): current(0), maxVertexAttributes(0)
#ifndef MAGNUM_TARGET_GLES
, maxAtomicCounterBufferSize(0), maxComputeSharedMemorySize(0), maxComputeWorkGroupInvocations(0), maxImageUnits(0), maxImageSamples(0), maxCombinedShaderOutputResources(0), maxUniformLocations(0), maxShaderStorageBlockSize(0)
#endif
#ifndef MAGNUM_TARGET_GLES2
, minTexelOffset(0), maxTexelOffset(0), maxUniformBlockSize(0)
#endif
{}
/* Currently used program */
GLuint current;
GLint maxSupportedVertexAttributeCount;
GLint maxVertexAttributes;
#ifndef MAGNUM_TARGET_GLES
GLint maxAtomicCounterBufferSize,
maxComputeSharedMemorySize,
maxComputeWorkGroupInvocations,
maxImageUnits,
maxImageSamples,
maxCombinedShaderOutputResources,
maxUniformLocations;
GLint64 maxShaderStorageBlockSize;
#endif
#ifndef MAGNUM_TARGET_GLES2
GLint minTexelOffset, maxTexelOffset, maxUniformBlockSize;
#endif
};
}}

92
src/Implementation/ShaderState.h

@ -0,0 +1,92 @@
#ifndef Magnum_Implementation_ShaderState_h
#define Magnum_Implementation_ShaderState_h
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "OpenGL.h"
#include "Types.h"
#include "magnumConfigure.h"
namespace Magnum { namespace Implementation {
struct ShaderState {
explicit ShaderState():
maxVertexOutputComponents{}, maxFragmentInputComponents{},
#ifndef MAGNUM_TARGET_GLES
maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{},
#endif
maxTextureImageUnits{}, maxTextureImageUnitsCombined{},
#ifndef MAGNUM_TARGET_GLES2
maxUniformBlocks{}, maxCombinedUniformBlocks{},
#endif
maxUniformComponents{}, maxUniformComponentsCombined{}
#ifndef MAGNUM_TARGET_GLES2
, maxCombinedUniformComponents{}
#endif
{}
enum: std::size_t {
#ifndef MAGNUM_TARGET_GLES
StageCount = 5
#else
StageCount = 2
#endif
};
GLint maxVertexOutputComponents,
maxFragmentInputComponents;
#ifndef MAGNUM_TARGET_GLES
GLint maxTessellationControlInputComponents,
maxTessellationControlOutputComponents,
maxTessellationControlTotalOutputComponents,
maxTessellationEvaluationInputComponents,
maxTessellationEvaluationOutputComponents,
maxGeometryInputComponents,
maxGeometryOutputComponents,
maxGeometryTotalOutputComponents;
GLint maxAtomicCounterBuffers[StageCount];
GLint maxCombinedAtomicCounterBuffers;
GLint maxAtomicCounters[StageCount];
GLint maxCombinedAtomicCounters;
GLint maxImageUniforms[StageCount];
GLint maxCombinedImageUniforms;
GLint maxShaderStorageBlocks[StageCount];
GLint maxCombinedShaderStorageBlocks;
#endif
GLint maxTextureImageUnits[StageCount];
GLint maxTextureImageUnitsCombined;
#ifndef MAGNUM_TARGET_GLES2
GLint maxUniformBlocks[StageCount];
GLint maxCombinedUniformBlocks;
#endif
GLint maxUniformComponents[StageCount];
GLint maxUniformComponentsCombined;
#ifndef MAGNUM_TARGET_GLES2
GLint maxCombinedUniformComponents[StageCount];
#endif
};
}}
#endif

15
src/Implementation/State.cpp

@ -24,12 +24,13 @@
#include "State.h"
#include "BufferState.h"
#include "FramebufferState.h"
#include "MeshState.h"
#include "RendererState.h"
#include "ShaderProgramState.h"
#include "TextureState.h"
#include "Implementation/BufferState.h"
#include "Implementation/FramebufferState.h"
#include "Implementation/MeshState.h"
#include "Implementation/RendererState.h"
#include "Implementation/ShaderState.h"
#include "Implementation/ShaderProgramState.h"
#include "Implementation/TextureState.h"
namespace Magnum { namespace Implementation {
@ -38,12 +39,14 @@ State::State():
framebuffer(new FramebufferState),
mesh(new MeshState),
renderer(new RendererState),
shader(new ShaderState),
shaderProgram(new ShaderProgramState),
texture(new TextureState) {}
State::~State() {
delete texture;
delete shaderProgram;
delete shader;
delete renderer;
delete mesh;
delete framebuffer;

2
src/Implementation/State.h

@ -30,6 +30,7 @@ struct BufferState;
struct FramebufferState;
struct MeshState;
struct RendererState;
struct ShaderState;
struct ShaderProgramState;
struct TextureState;
@ -41,6 +42,7 @@ struct State {
FramebufferState* const framebuffer;
MeshState* const mesh;
RendererState* const renderer;
ShaderState* const shader;
ShaderProgramState* const shaderProgram;
TextureState* const texture;
};

139
src/Platform/magnum-info.cpp

@ -29,7 +29,10 @@
#include <Utility/NaClStreamBuffer.h>
#endif
#include "AbstractShaderProgram.h"
#include "Context.h"
#include "Extensions.h"
#include "Shader.h"
#ifndef CORRADE_TARGET_NACL
#include "Platform/WindowlessGlxApplication.h"
#else
@ -169,6 +172,142 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
Debug() << "";
}
/* 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;
Debug() << "Limits and implementation-defined values:";
_l(Shader::maxVertexOutputComponents())
_l(Shader::maxFragmentInputComponents())
_l(Shader::maxTextureImageUnits(Shader::Type::Vertex))
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxTextureImageUnits(Shader::Type::TessellationControl))
_l(Shader::maxTextureImageUnits(Shader::Type::TessellationEvaluation))
_l(Shader::maxTextureImageUnits(Shader::Type::Geometry))
_l(Shader::maxTextureImageUnits(Shader::Type::Compute))
#endif
_l(Shader::maxTextureImageUnits(Shader::Type::Fragment))
_l(Shader::maxCombinedTextureImageUnits())
_l(Shader::maxUniformComponents(Shader::Type::Vertex))
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxUniformComponents(Shader::Type::TessellationControl))
_l(Shader::maxUniformComponents(Shader::Type::TessellationEvaluation))
_l(Shader::maxUniformComponents(Shader::Type::Geometry))
_l(Shader::maxUniformComponents(Shader::Type::Compute))
#endif
_l(Shader::maxUniformComponents(Shader::Type::Fragment))
#ifndef MAGNUM_TARGET_GLES
_l(AbstractShaderProgram::maxUniformLocations())
#endif
_l(AbstractShaderProgram::maxVertexAttributes())
#ifndef MAGNUM_TARGET_GLES
if(c->isExtensionSupported<Extensions::GL::ARB::compute_shader>()) {
_h(ARB::compute_shader)
_l(AbstractShaderProgram::maxComputeSharedMemorySize())
_l(AbstractShaderProgram::maxComputeWorkGroupInvocations())
}
if(c->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>()) {
_h(ARB::geometry_shader4)
_l(Shader::maxGeometryInputComponents())
_l(Shader::maxGeometryOutputComponents())
_l(Shader::maxGeometryTotalOutputComponents())
}
if(c->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>()) {
_h(ARB::shader_atomic_counters)
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Vertex))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationControl))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationEvaluation))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Compute))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Fragment))
_l(Shader::maxCombinedAtomicCounterBuffers())
_l(Shader::maxAtomicCounters(Shader::Type::Vertex))
_l(Shader::maxAtomicCounters(Shader::Type::TessellationControl))
_l(Shader::maxAtomicCounters(Shader::Type::TessellationEvaluation))
_l(Shader::maxAtomicCounters(Shader::Type::Geometry))
_l(Shader::maxAtomicCounters(Shader::Type::Compute))
_l(Shader::maxAtomicCounters(Shader::Type::Fragment))
_l(Shader::maxCombinedAtomicCounters())
_l(AbstractShaderProgram::maxAtomicCounterBufferSize())
}
if(c->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>()) {
_h(ARB::shader_image_load_store)
_l(Shader::maxImageUniforms(Shader::Type::Vertex))
_l(Shader::maxImageUniforms(Shader::Type::TessellationControl))
_l(Shader::maxImageUniforms(Shader::Type::TessellationEvaluation))
_l(Shader::maxImageUniforms(Shader::Type::Geometry))
_l(Shader::maxImageUniforms(Shader::Type::Compute))
_l(Shader::maxImageUniforms(Shader::Type::Fragment))
_l(Shader::maxCombinedImageUniforms())
_l(AbstractShaderProgram::maxCombinedShaderOutputResources())
_l(AbstractShaderProgram::maxImageUnits())
_l(AbstractShaderProgram::maxImageSamples())
}
if(c->isExtensionSupported<Extensions::GL::ARB::shader_storage_buffer_object>()) {
_h(ARB::shader_storage_buffer_object)
_l(Shader::maxShaderStorageBlocks(Shader::Type::Vertex))
_l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationControl))
_l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationEvaluation))
_l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry))
_l(Shader::maxShaderStorageBlocks(Shader::Type::Compute))
_l(Shader::maxShaderStorageBlocks(Shader::Type::Fragment))
_l(Shader::maxCombinedShaderStorageBlocks())
/* AbstractShaderProgram::maxCombinedShaderOutputResources() already in shader_image_load_store */
_l(AbstractShaderProgram::maxShaderStorageBlockSize())
}
if(c->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>()) {
_h(ARB::tessellation_shader)
_l(Shader::maxTessellationControlInputComponents())
_l(Shader::maxTessellationControlOutputComponents())
_l(Shader::maxTessellationControlTotalOutputComponents())
_l(Shader::maxTessellationEvaluationInputComponents())
_l(Shader::maxTessellationEvaluationOutputComponents())
}
#endif
#ifndef MAGNUM_TARGET_GLES2
if(c->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>()) {
_h(ARB::uniform_buffer_object)
_l(Shader::maxUniformBlocks(Shader::Type::Vertex))
_l(Shader::maxUniformBlocks(Shader::Type::TessellationControl))
_l(Shader::maxUniformBlocks(Shader::Type::TessellationEvaluation))
_l(Shader::maxUniformBlocks(Shader::Type::Geometry))
_l(Shader::maxUniformBlocks(Shader::Type::Compute))
_l(Shader::maxUniformBlocks(Shader::Type::Fragment))
_l(Shader::maxCombinedUniformBlocks())
_l(Shader::maxCombinedUniformComponents(Shader::Type::Vertex))
_l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationControl))
_l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationEvaluation))
_l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry))
_l(Shader::maxCombinedUniformComponents(Shader::Type::Compute))
_l(Shader::maxCombinedUniformComponents(Shader::Type::Fragment))
_l(AbstractShaderProgram::maxUniformBlockSize())
}
if(c->isExtensionSupported<Extensions::GL::EXT::gpu_shader4>()) {
_h(EXT::gpu_shader4)
_l(AbstractShaderProgram::minTexelOffset())
_l(AbstractShaderProgram::maxTexelOffset())
}
#endif
#undef _l
#undef _h
}
}

476
src/Shader.cpp

@ -27,6 +27,10 @@
#include <fstream>
#include <Utility/Assert.h>
#include "Extensions.h"
#include "Implementation/State.h"
#include "Implementation/ShaderState.h"
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(_WIN32)
#include <sstream>
#endif
@ -55,7 +59,479 @@ std::string shaderName(const Shader::Type type) {
CORRADE_ASSERT_UNREACHABLE();
}
UnsignedInt typeToIndex(const Shader::Type type) {
switch(type) {
case Shader::Type::Vertex: return 0;
case Shader::Type::Fragment: return 1;
#ifndef MAGNUM_TARGET_GLES
case Shader::Type::Geometry: return 2;
case Shader::Type::TessellationControl: return 3;
case Shader::Type::TessellationEvaluation: return 4;
case Shader::Type::Compute: return 5;
#endif
}
CORRADE_ASSERT_UNREACHABLE();
}
#ifndef MAGNUM_TARGET_GLES
bool isTypeSupported(const Shader::Type type) {
if(type == Shader::Type::Geometry && !Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return false;
if((type == Shader::Type::TessellationControl || type == Shader::Type::TessellationEvaluation) && !Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>())
return false;
if(type == Shader::Type::Compute && !Context::current()->isExtensionSupported<Extensions::GL::ARB::compute_shader>())
return false;
return true;
}
#else
constexpr bool isTypeSupported(Shader::Type) { return true; }
#endif
}
Int Shader::maxVertexOutputComponents() {
GLint& value = Context::current()->state().shader->maxVertexOutputComponents;
/* Get the value, if not already cached */
if(value == 0) {
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isVersionSupported(Version::GL320))
glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &value);
else
glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &value);
#elif defined(MAGNUM_TARGET_GLES2)
glGetIntegerv(GL_MAX_VARYING_VECTORS, &value);
value *= 4;
#else
glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &value);
#endif
}
return value;
}
#ifndef MAGNUM_TARGET_GLES
Int Shader::maxTessellationControlInputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>())
return 0;
GLint& value = Context::current()->state().shader->maxTessellationControlInputComponents;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxTessellationControlOutputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>())
return 0;
GLint& value = Context::current()->state().shader->maxTessellationControlOutputComponents;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxTessellationControlTotalOutputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>())
return 0;
GLint& value = Context::current()->state().shader->maxTessellationControlTotalOutputComponents;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxTessellationEvaluationInputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>())
return 0;
GLint& value = Context::current()->state().shader->maxTessellationEvaluationInputComponents;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxTessellationEvaluationOutputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::tessellation_shader>())
return 0;
GLint& value = Context::current()->state().shader->maxTessellationEvaluationOutputComponents;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxGeometryInputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return 0;
GLint& value = Context::current()->state().shader->maxGeometryInputComponents;
/* Get the value, if not already cached */
/** @todo The extension has only `GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB`, this is supported since GL 3.2 (wtf?) */
if(value == 0)
glGetIntegerv(GL_MAX_GEOMETRY_INPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxGeometryOutputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return 0;
GLint& value = Context::current()->state().shader->maxGeometryOutputComponents;
/* Get the value, if not already cached */
/** @todo The extension has only `GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB`, this is supported since GL 3.2 (wtf?) */
if(value == 0)
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &value);
return value;
}
Int Shader::maxGeometryTotalOutputComponents() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return 0;
GLint& value = Context::current()->state().shader->maxGeometryTotalOutputComponents;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &value);
return value;
}
#endif
Int Shader::maxFragmentInputComponents() {
GLint& value = Context::current()->state().shader->maxFragmentInputComponents;
/* Get the value, if not already cached */
if(value == 0) {
#ifndef MAGNUM_TARGET_GLES
if(Context::current()->isVersionSupported(Version::GL320))
glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &value);
else
glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &value);
#elif defined(MAGNUM_TARGET_GLES2)
glGetIntegerv(GL_MAX_VARYING_VECTORS, &value);
value *= 4;
#else
glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &value);
#endif
}
return value;
}
#ifndef MAGNUM_TARGET_GLES
Int Shader::maxAtomicCounterBuffers(const Type type) {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>() || !isTypeSupported(type))
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxAtomicCounterBuffers[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS,
GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS,
GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,
GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS,
GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS,
GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
Int Shader::maxCombinedAtomicCounterBuffers() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>())
return 0;
GLint& value = Context::current()->state().shader->maxCombinedAtomicCounterBuffers;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, &value);
return value;
}
Int Shader::maxAtomicCounters(const Type type) {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>() || !isTypeSupported(type))
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxAtomicCounters[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_ATOMIC_COUNTERS,
GL_MAX_FRAGMENT_ATOMIC_COUNTERS,
GL_MAX_GEOMETRY_ATOMIC_COUNTERS,
GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS,
GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS,
GL_MAX_COMPUTE_ATOMIC_COUNTERS
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
Int Shader::maxCombinedAtomicCounters() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>())
return 0;
GLint& value = Context::current()->state().shader->maxCombinedAtomicCounters;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTERS, &value);
return value;
}
Int Shader::maxImageUniforms(const Type type) {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>() || !isTypeSupported(type))
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxImageUniforms[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_IMAGE_UNIFORMS,
GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS,
GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS,
GL_MAX_COMPUTE_IMAGE_UNIFORMS
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
Int Shader::maxCombinedImageUniforms() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_image_load_store>())
return 0;
GLint& value = Context::current()->state().shader->maxCombinedImageUniforms;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_IMAGE_UNIFORMS, &value);
return value;
}
Int Shader::maxShaderStorageBlocks(const Type type) {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_storage_buffer_object>() || !isTypeSupported(type))
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxShaderStorageBlocks[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS,
GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,
GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,
GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,
GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
Int Shader::maxCombinedShaderStorageBlocks() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::shader_atomic_counters>())
return 0;
GLint& value = Context::current()->state().shader->maxCombinedShaderStorageBlocks;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &value);
return value;
}
#endif
Int Shader::maxTextureImageUnits(const Type type) {
if(!isTypeSupported(type))
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxTextureImageUnits[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
GL_MAX_TEXTURE_IMAGE_UNITS,
#ifndef MAGNUM_TARGET_GLES
GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS,
GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,
GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,
GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS
#endif
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
Int Shader::maxCombinedTextureImageUnits() {
GLint& value = Context::current()->state().shader->maxTextureImageUnitsCombined;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &value);
return value;
}
#ifndef MAGNUM_TARGET_GLES2
Int Shader::maxUniformBlocks(const Type type) {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>() || !isTypeSupported(type))
#else
if(!isTypeSupported(type))
#endif
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxUniformBlocks[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_UNIFORM_BLOCKS,
GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
#ifndef MAGNUM_TARGET_GLES
/** @todo Fix this when glLoadGen has GL_MAX_GEOMETRY_UNIFORM_BLOCKS enum */
0x8A2C /*GL_MAX_GEOMETRY_UNIFORM_BLOCKS*/,
GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,
GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,
GL_MAX_COMPUTE_UNIFORM_BLOCKS
#endif
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
Int Shader::maxCombinedUniformBlocks() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>())
return 0;
#endif
GLint& value = Context::current()->state().shader->maxCombinedUniformBlocks;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &value);
return value;
}
#endif
Int Shader::maxUniformComponents(const Type type) {
if(!isTypeSupported(type))
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxUniformComponents[index];
/* Get the value, if not already cached */
#ifndef MAGNUM_TARGET_GLES2
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_UNIFORM_COMPONENTS,
GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
#ifndef MAGNUM_TARGET_GLES
GL_MAX_GEOMETRY_UNIFORM_COMPONENTS,
GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS,
GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS,
GL_MAX_COMPUTE_UNIFORM_COMPONENTS
#endif
};
if(value == 0)
glGetIntegerv(what[index], &value);
#else
/* For ES2 we need to multiply _VECTORS by 4 */
constexpr static const GLenum what[] = {
GL_MAX_VERTEX_UNIFORM_VECTORS,
GL_MAX_FRAGMENT_UNIFORM_VECTORS
};
if(value == 0) {
GLint vectors;
glGetIntegerv(what[index], &vectors);
value = vectors*4;
}
#endif
return value;
}
#ifndef MAGNUM_TARGET_GLES2
Int Shader::maxCombinedUniformComponents(const Type type) {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::uniform_buffer_object>() || !isTypeSupported(type))
#else
if(!isTypeSupported(type))
#endif
return 0;
const UnsignedInt index = typeToIndex(type);
GLint& value = Context::current()->state().shader->maxCombinedUniformComponents[index];
/* Get the value, if not already cached */
constexpr static const GLenum what[] = {
GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
#ifndef MAGNUM_TARGET_GLES
/** @todo Fix this when glLoadGen has GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS enum */
0x8A32 /*GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS*/,
GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS,
GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS,
GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS
#endif
};
if(value == 0)
glGetIntegerv(what[index], &value);
return value;
}
#endif
Shader::Shader(const Version version, const Type type): _type(type), _id(0) {
_id = glCreateShader(static_cast<GLenum>(_type));

345
src/Shader.h

@ -48,7 +48,19 @@ class MAGNUM_EXPORT Shader {
Shader& operator=(const Shader&) = delete;
public:
/** @brief %Shader type */
/**
* @brief %Shader type
*
* @see @ref Shader(Version, Type),
* @ref maxAtomicCounterBuffers(),
* @ref maxAtomicCounters(),
* @ref maxImageUniforms()
* @ref maxShaderStorageBlocks(),
* @ref maxTextureImageUnits(),
* @ref maxUniformBlocks(),
* @ref maxUniformComponents(),
* @ref maxCombinedUniformComponents()
*/
enum class Type: GLenum {
Vertex = GL_VERTEX_SHADER, /**< Vertex shader */
@ -85,6 +97,337 @@ class MAGNUM_EXPORT Shader {
Fragment = GL_FRAGMENT_SHADER /**< Fragment shader */
};
/**
* @brief Max supported component count on vertex shader output
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. In OpenGL ES 2.0 the four-component vector count is
* queried and multiplied with 4.
* @see @fn_gl{Get} with @def_gl{MAX_VERTEX_OUTPUT_COMPONENTS},
* @def_gl{MAX_VARYING_COMPONENTS} in OpenGL <3.2 or
* @def_gl{MAX_VARYING_VECTORS} in OpenGL ES 2.0
*/
static Int maxVertexOutputComponents();
/** @todo `GL_MAX_PATCH_VERTICES`, `GL_MAX_TESS_GEN_LEVEL`, `GL_MAX_TESS_PATCH_COMPONENTS` when @extension{ARB,tessellation_shader} is done */
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Max supported component count of tessellation control shader input vertex
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,tessellation_shader}
* is not available, returns `0`.
* @requires_gl Tessellation shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_TESS_CONTROL_INPUT_COMPONENTS}
*/
static Int maxTessellationControlInputComponents();
/**
* @brief Max supported component count of tessellation control shader output vertex
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,tessellation_shader}
* is not available, returns `0`.
* @requires_gl Tessellation shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_TESS_CONTROL_OUTPUT_COMPONENTS}
*/
static Int maxTessellationControlOutputComponents();
/**
* @brief Max supported component count of all tessellation control shader output vertices combined
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,tessellation_shader}
* is not available, returns `0`.
* @requires_gl Tessellation shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS}
*/
static Int maxTessellationControlTotalOutputComponents();
/**
* @brief Max supported component count of tessellation evaluation shader input vertex
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,tessellation_shader}
* is not available, returns `0`.
* @requires_gl Tessellation shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_TESS_EVALUATION_INPUT_COMPONENTS}
*/
static Int maxTessellationEvaluationInputComponents();
/**
* @brief Max supported component count of tessellation evaluation shader output vertex
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,tessellation_shader}
* is not available, returns `0`.
* @requires_gl Tessellation shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_TESS_EVALUATION_OUTPUT_COMPONENTS}
*/
static Int maxTessellationEvaluationOutputComponents();
/**
* @brief Max supported component count of geometry shader input vertex
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,geometry_shader4}
* is not available, returns `0`.
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_INPUT_COMPONENTS}
*/
static Int maxGeometryInputComponents();
/**
* @brief Max supported component count of geometry shader output vertex
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,geometry_shader4}
* is not available, returns `0`.
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_OUTPUT_COMPONENTS}
*/
static Int maxGeometryOutputComponents();
/**
* @brief Max supported component count of all geometry shader output vertices combined
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,geometry_shader4}
* is not available, returns `0`.
* @requires_gl Geometry shaders are not available in OpenGL ES.
* @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS}
*/
static Int maxGeometryTotalOutputComponents();
#endif
/**
* @brief Max supported component count on fragment shader input
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. In OpenGL ES 2.0 the four-component vector count is
* queried and multiplied with 4.
* @see @fn_gl{Get} with @def_gl{MAX_FRAGMENT_INPUT_COMPONENTS},
* @def_gl{MAX_VARYING_COMPONENTS} in OpenGL <3.2 or
* @def_gl{MAX_VARYING_VECTORS} in OpenGL ES 2.0
*/
static Int maxFragmentInputComponents();
/**
* @brief Max supported uniform component count in default block
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If particular shader stage is not available, returns
* `0`. In OpenGL ES 2.0 the four-component vector count is queried and
* multiplied with 4.
* @see @ref maxCombinedUniformComponents(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_UNIFORM_COMPONENTS},
* @def_gl{MAX_TESS_CONTROL_UNIFORM_COMPOENTS},
* @def_gl{MAX_TESS_EVALUATION_UNIFORM_COMPONENTS},
* @def_gl{MAX_GEOMETRY_UNIFORM_COMPONENTS},
* @def_gl{MAX_COMPUTE_UNIFORM_COMPONENTS},
* @def_gl{MAX_FRAGMENT_UNIFORM_COMPONENTS} or
* @def_gl{MAX_VERTEX_UNIFORM_VECTORS},
* @def_gl{MAX_FRAGMENT_UNIFORM_VECTORS} in OpenGL ES 2.0
*/
static Int maxUniformComponents(Type type);
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Max supported atomic counter buffer count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_atomic_counters} or
* particular shader stage is not available, returns `0`.
* @requires_gl Atomic counters are not available in OpenGL ES.
* @see @ref maxCombinedAtomicCounterBuffers(), @ref maxAtomicCounters(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_ATOMIC_COUNTER_BUFFERS},
* @def_gl{MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS},
* @def_gl{MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS},
* @def_gl{MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS},
* @def_gl{MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS} or
* @def_gl{MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS}
*/
static Int maxAtomicCounterBuffers(Type type);
/**
* @brief Max supported atomic counter buffer count for all stages combined
*
* 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`.
* @requires_gl Atomic counters are not available in OpenGL ES.
* @see @ref maxAtomicCounterBuffers(), @ref maxCombinedAtomicCounters(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_ATOMIC_COUNTER_BUFFERS}
*/
static Int maxCombinedAtomicCounterBuffers();
/**
* @brief Max supported atomic counter count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_atomic_counters} or
* particular shader stage is not available, returns `0`.
* @requires_gl Atomic counters are not available in OpenGL ES.
* @see @ref maxCombinedAtomicCounters(), @ref maxAtomicCounterBuffers(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_ATOMIC_COUNTERS},
* @def_gl{MAX_TESS_CONTROL_ATOMIC_COUNTERS},
* @def_gl{MAX_TESS_EVALUATION_ATOMIC_COUNTERS},
* @def_gl{MAX_GEOMETRY_ATOMIC_COUNTERS},
* @def_gl{MAX_COMPUTE_ATOMIC_COUNTERS} or
* @def_gl{MAX_FRAGMENT_ATOMIC_COUNTERS}
*/
static Int maxAtomicCounters(Type type);
/**
* @brief Max supported atomic counter count for all stages combined
*
* 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`.
* @requires_gl Atomic counters are not available in OpenGL ES.
* @see @ref maxAtomicCounters(), @ref maxCombinedAtomicCounterBuffers(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_ATOMIC_COUNTERS}
*/
static Int maxCombinedAtomicCounters();
/**
* @brief Max supported image uniform count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_image_load_store}
* or particular shader stage is not available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @ref maxCombinedImageUniforms(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_IMAGE_UNIFORMS},
* @def_gl{MAX_TESS_CONTROL_IMAGE_UNIFORMS},
* @def_gl{MAX_TESS_EVALUATION_IMAGE_UNIFORMS},
* @def_gl{MAX_GEOMETRY_IMAGE_UNIFORMS},
* @def_gl{MAX_COMPUTE_IMAGE_UNIFORMS} or
* @def_gl{MAX_FRAGMENT_IMAGE_UNIFORMS}
*/
static Int maxImageUniforms(Type type);
/**
* @brief Max supported image uniform count for all stages combined
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_image_load_store}
* is not available, returns `0`.
* @requires_gl Image load/store is not available in OpenGL ES.
* @see @ref maxImageUniforms(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_IMAGE_UNIFORMS}
*/
static Int maxCombinedImageUniforms();
/**
* @brief Max supported shader storage block count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,shader_storage_buffer_object}
* or particular shader stage is not available, returns `0`.
* @requires_gl Shader storage is not available in OpenGL ES.
* @see @ref maxCombinedShaderStorageBlocks(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_SHADER_STORAGE_BLOCKS},
* @def_gl{MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS},
* @def_gl{MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS},
* @def_gl{MAX_GEOMETRY_SHADER_STORAGE_BLOCKS},
* @def_gl{MAX_COMPUTE_SHADER_STORAGE_BLOCKS} or
* @def_gl{MAX_FRAGMENT_SHADER_STORAGE_BLOCKS}
*/
static Int maxShaderStorageBlocks(Type type);
/**
* @brief Max supported shader storage block count for all stages combined
*
* 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`.
* @requires_gl Shader storage is not available in OpenGL ES.
* @see @ref maxShaderStorageBlocks(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_SHADER_STORAGE_BLOCKS}
*/
static Int maxCombinedShaderStorageBlocks();
#endif
/**
* @brief Max supported texture image unit count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If particular shader stage is not available, returns
* `0`.
* @see @ref maxCombinedTextureImageUnits(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_TEXTURE_IMAGE_UNITS},
* @fn_gl{MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS},
* @fn_gl{MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS},
* @fn_gl{MAX_GEOMETRY_TEXTURE_IMAGE_UNITS},
* @fn_gl{MAX_COMPUTE_TEXTURE_IMAGE_UNITS},
* @fn_gl{MAX_TEXTURE_IMAGE_UNITS}
*/
static Int maxTextureImageUnits(Type type);
/**
* @brief Max supported texture image unit count for all stages combined
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls.
* @see @ref AbstractTexture::maxLayers(), @ref maxTextureImageUnits(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_TEXTURE_IMAGE_UNITS}
*/
static Int maxCombinedTextureImageUnits();
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Max supported uniform block count
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,uniform_buffer_objects} or
* particular shader stage is not available, returns `0`.
* @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
* @see @ref maxCombinedUniformBlocks(), @ref maxUniformComponents(),
* @ref maxCombinedUniformComponents(),
* @fn_gl{Get} with @def_gl{MAX_VERTEX_UNIFORM_BLOCKS},
* @def_gl{MAX_TESS_CONTROL_UNIFORM_BLOCKS},
* @def_gl{MAX_TESS_EVALUATION_UNIFORM_BLOCKS},
* @def_gl{MAX_GEOMETRY_UNIFORM_BLOCKS},
* @def_gl{MAX_COMPUTE_UNIFORM_BLOCKS} or
* @def_gl{MAX_FRAGMENT_UNIFORM_BLOCKS}
*/
static Int maxUniformBlocks(Type type);
/**
* @brief Max supported uniform block count for all stages combined
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,uniform_buffer_objects} is
* not available, returns `0`.
* @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
* @see @ref maxUniformBlocks(), @ref maxUniformComponents(),
* @ref maxCombinedUniformComponents(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_UNIFORM_BLOCKS}
*/
static Int maxCombinedUniformBlocks();
#endif
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Max supported uniform component count in all blocks combined
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If extension @extension{ARB,uniform_buffer_objects}
* or particular shader stage is not available, returns `0`.
* @requires_gles30 Uniform blocks are not available in OpenGL ES 2.0.
* @see @ref maxUniformComponents(), @ref maxUniformBlocks(),
* @fn_gl{Get} with @def_gl{MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS},
* @def_gl{MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS},
* @def_gl{MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS},
* @def_gl{MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS},
* @def_gl{MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS} or
* @def_gl{MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS}
*/
static Int maxCombinedUniformComponents(Type type);
#endif
/**
* @brief Constructor
* @param version Target version

Loading…
Cancel
Save