Browse Source

Implemented EXT_geometry_shader AEP extension.

pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
52be3a44b1
  1. 4
      doc/opengl-support.dox
  2. 14
      src/Magnum/Implementation/ShaderState.h
  3. 27
      src/Magnum/Platform/magnum-info.cpp
  4. 71
      src/Magnum/Shader.cpp
  5. 44
      src/Magnum/Shader.h

4
doc/opengl-support.dox

@ -92,7 +92,7 @@ GLSL 1.40 | done
Extension | Status
------------------------------------------- | ------
GLSL 1.50 | done
@extension{ARB,geometry_shader4} | missing layered attachments
@extension{ARB,geometry_shader4} | missing layered attachments and some limit queries
@extension{ARB,depth_clamp} | done
@extension{ARB,draw_elements_base_vertex} | done
@extension{ARB,fragment_coord_conventions} | done (shading language only)
@ -362,7 +362,7 @@ Extension | Status
@es_extension{EXT,shader_integer_mix} | done (shading language only)
@es_extension{EXT,copy_image} | |
@es_extension{EXT,draw_buffers_indexed} | |
@es_extension{EXT,geometry_shader} | |
@es_extension{EXT,geometry_shader} | missing some ES-specific limit queries
@es_extension{EXT,gpu_shader5} | done (shading language only)
@es_extension{EXT,shader_io_blocks} | done (shading language only)
@es_extension{EXT,tessellation_shader} | |

14
src/Magnum/Implementation/ShaderState.h

@ -35,10 +35,10 @@ struct ShaderState {
explicit ShaderState():
maxVertexOutputComponents{}, maxFragmentInputComponents{},
#ifndef MAGNUM_TARGET_GLES
maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{}, maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{},
maxTessellationControlInputComponents{}, maxTessellationControlOutputComponents{}, maxTessellationControlTotalOutputComponents{}, maxTessellationEvaluationInputComponents{}, maxTessellationEvaluationOutputComponents{},
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{},
maxGeometryInputComponents{}, maxGeometryOutputComponents{}, maxGeometryTotalOutputComponents{}, maxAtomicCounterBuffers{}, maxCombinedAtomicCounterBuffers{}, maxAtomicCounters{}, maxCombinedAtomicCounters{}, maxImageUniforms{}, maxCombinedImageUniforms{}, maxShaderStorageBlocks{}, maxCombinedShaderStorageBlocks{},
#endif
maxTextureImageUnits{}, maxTextureImageUnitsCombined{},
#ifndef MAGNUM_TARGET_GLES2
@ -54,7 +54,7 @@ struct ShaderState {
#ifndef MAGNUM_TARGET_GLES
StageCount = 6
#elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
StageCount = 3
StageCount = 4
#else
StageCount = 2
#endif
@ -67,12 +67,12 @@ struct ShaderState {
maxTessellationControlOutputComponents,
maxTessellationControlTotalOutputComponents,
maxTessellationEvaluationInputComponents,
maxTessellationEvaluationOutputComponents,
maxGeometryInputComponents,
maxGeometryOutputComponents,
maxGeometryTotalOutputComponents;
maxTessellationEvaluationOutputComponents;
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
GLint maxGeometryInputComponents,
maxGeometryOutputComponents,
maxGeometryTotalOutputComponents;
GLint maxAtomicCounterBuffers[StageCount];
GLint maxCombinedAtomicCounterBuffers;
GLint maxAtomicCounters[StageCount];

27
src/Magnum/Platform/magnum-info.cpp

@ -320,9 +320,9 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxTextureImageUnits(Shader::Type::TessellationControl))
_l(Shader::maxTextureImageUnits(Shader::Type::TessellationEvaluation))
_l(Shader::maxTextureImageUnits(Shader::Type::Geometry))
#endif
#ifndef MAGNUM_TARGET_GLES2
_l(Shader::maxTextureImageUnits(Shader::Type::Geometry))
_l(Shader::maxTextureImageUnits(Shader::Type::Compute))
#endif
_l(Shader::maxTextureImageUnits(Shader::Type::Fragment))
@ -331,9 +331,9 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxUniformComponents(Shader::Type::TessellationControl))
_l(Shader::maxUniformComponents(Shader::Type::TessellationEvaluation))
_l(Shader::maxUniformComponents(Shader::Type::Geometry))
#endif
#ifndef MAGNUM_TARGET_GLES2
_l(Shader::maxUniformComponents(Shader::Type::Geometry))
_l(Shader::maxUniformComponents(Shader::Type::Compute))
#endif
_l(Shader::maxUniformComponents(Shader::Type::Fragment))
@ -383,9 +383,18 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
#ifndef MAGNUM_TARGET_GLES
if(c->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>()) {
if(c->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
#else
if(c->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
#endif
{
#ifndef MAGNUM_TARGET_GLES
_h(ARB::geometry_shader4)
#else
_h(EXT::geometry_shader)
#endif
_l(Shader::maxGeometryInputComponents())
_l(Shader::maxGeometryOutputComponents())
@ -407,8 +416,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationControl))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::TessellationEvaluation))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry))
#endif
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Geometry))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Compute))
_l(Shader::maxAtomicCounterBuffers(Shader::Type::Fragment))
_l(Shader::maxCombinedAtomicCounterBuffers())
@ -416,8 +425,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxAtomicCounters(Shader::Type::TessellationControl))
_l(Shader::maxAtomicCounters(Shader::Type::TessellationEvaluation))
_l(Shader::maxAtomicCounters(Shader::Type::Geometry))
#endif
_l(Shader::maxAtomicCounters(Shader::Type::Geometry))
_l(Shader::maxAtomicCounters(Shader::Type::Compute))
_l(Shader::maxAtomicCounters(Shader::Type::Fragment))
_l(Shader::maxCombinedAtomicCounters())
@ -436,8 +445,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxImageUniforms(Shader::Type::TessellationControl))
_l(Shader::maxImageUniforms(Shader::Type::TessellationEvaluation))
_l(Shader::maxImageUniforms(Shader::Type::Geometry))
#endif
_l(Shader::maxImageUniforms(Shader::Type::Geometry))
_l(Shader::maxImageUniforms(Shader::Type::Compute))
_l(Shader::maxImageUniforms(Shader::Type::Fragment))
_l(Shader::maxCombinedImageUniforms())
@ -460,8 +469,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationControl))
_l(Shader::maxShaderStorageBlocks(Shader::Type::TessellationEvaluation))
_l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry))
#endif
_l(Shader::maxShaderStorageBlocks(Shader::Type::Geometry))
_l(Shader::maxShaderStorageBlocks(Shader::Type::Compute))
_l(Shader::maxShaderStorageBlocks(Shader::Type::Fragment))
_l(Shader::maxCombinedShaderStorageBlocks())
@ -570,8 +579,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxUniformBlocks(Shader::Type::TessellationControl))
_l(Shader::maxUniformBlocks(Shader::Type::TessellationEvaluation))
_l(Shader::maxUniformBlocks(Shader::Type::Geometry))
#endif
_l(Shader::maxUniformBlocks(Shader::Type::Geometry))
_l(Shader::maxUniformBlocks(Shader::Type::Compute))
_l(Shader::maxUniformBlocks(Shader::Type::Fragment))
_l(Shader::maxCombinedUniformBlocks())
@ -579,8 +588,8 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
#ifndef MAGNUM_TARGET_GLES
_l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationControl))
_l(Shader::maxCombinedUniformComponents(Shader::Type::TessellationEvaluation))
_l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry))
#endif
_l(Shader::maxCombinedUniformComponents(Shader::Type::Geometry))
_l(Shader::maxCombinedUniformComponents(Shader::Type::Compute))
_l(Shader::maxCombinedUniformComponents(Shader::Type::Fragment))
_l(AbstractShaderProgram::maxUniformBlockSize())

71
src/Magnum/Shader.cpp

@ -60,8 +60,10 @@ namespace {
std::string shaderName(const Shader::Type type) {
switch(type) {
case Shader::Type::Vertex: return "vertex";
#ifndef MAGNUM_TARGET_GLES
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
case Shader::Type::Geometry: return "geometry";
#endif
#ifndef MAGNUM_TARGET_GLES
case Shader::Type::TessellationControl: return "tessellation control";
case Shader::Type::TessellationEvaluation: return "tessellation evaluation";
#endif
@ -80,9 +82,9 @@ UnsignedInt typeToIndex(const Shader::Type type) {
case Shader::Type::Fragment: return 1;
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
case Shader::Type::Compute: return 2;
case Shader::Type::Geometry: return 3;
#endif
#ifndef MAGNUM_TARGET_GLES
case Shader::Type::Geometry: return 3;
case Shader::Type::TessellationControl: return 4;
case Shader::Type::TessellationEvaluation: return 5;
#endif
@ -106,6 +108,9 @@ bool isTypeSupported(const Shader::Type type) {
}
#elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
bool isTypeSupported(const Shader::Type type) {
if(type == Shader::Type::Geometry && !Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
return false;
if(type == Shader::Type::Compute && !Context::current()->isVersionSupported(Version::GLES310))
return false;
@ -203,44 +208,76 @@ Int Shader::maxTessellationEvaluationOutputComponents() {
return value;
}
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
Int Shader::maxGeometryInputComponents() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return 0;
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
return 0;
#endif
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);
if(value == 0) glGetIntegerv(
#ifndef MAGNUM_TARGET_GLES
GL_MAX_GEOMETRY_INPUT_COMPONENTS,
#else
GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT,
#endif
&value);
return value;
}
Int Shader::maxGeometryOutputComponents() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return 0;
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
return 0;
#endif
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);
if(value == 0) glGetIntegerv(
#ifndef MAGNUM_TARGET_GLES
GL_MAX_GEOMETRY_OUTPUT_COMPONENTS,
#else
GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT,
#endif
&value);
return value;
}
Int Shader::maxGeometryTotalOutputComponents() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::geometry_shader4>())
return 0;
#else
if(!Context::current()->isExtensionSupported<Extensions::GL::EXT::geometry_shader>())
return 0;
#endif
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);
if(value == 0) glGetIntegerv(
#ifndef MAGNUM_TARGET_GLES
GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
#else
GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT,
#endif
&value);
return value;
}
@ -294,6 +331,8 @@ Int Shader::maxAtomicCounterBuffers(const Type type) {
GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,
GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS,
GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS
#else
GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT
#endif
};
if(value == 0)
@ -345,6 +384,8 @@ Int Shader::maxAtomicCounters(const Type type) {
GL_MAX_GEOMETRY_ATOMIC_COUNTERS,
GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS,
GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS,
#else
GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT
#endif
};
if(value == 0)
@ -396,6 +437,8 @@ Int Shader::maxImageUniforms(const Type type) {
GL_MAX_GEOMETRY_IMAGE_UNIFORMS,
GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS,
GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS
#else
GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT
#endif
};
if(value == 0)
@ -447,6 +490,8 @@ Int Shader::maxShaderStorageBlocks(const Type type) {
GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,
GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS
#else
GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT
#endif
};
if(value == 0)
@ -491,6 +536,8 @@ Int Shader::maxTextureImageUnits(const Type type) {
GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS,
GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,
GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS
#elif !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT
#endif
};
if(value == 0)
@ -532,6 +579,8 @@ Int Shader::maxUniformBlocks(const Type type) {
GL_MAX_GEOMETRY_UNIFORM_BLOCKS,
GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,
GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS
#elif !defined(MAGNUM_TARGET_WEBGL)
GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT
#endif
};
if(value == 0)
@ -575,6 +624,8 @@ Int Shader::maxUniformComponents(const Type type) {
GL_MAX_GEOMETRY_UNIFORM_COMPONENTS,
GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS,
GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS
#elif !defined(MAGNUM_TARGET_WEBGL)
GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT
#endif
};
if(value == 0)
@ -618,6 +669,8 @@ Int Shader::maxCombinedUniformComponents(const Type type) {
GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS,
GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS,
GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS
#elif !defined(MAGNUM_TARGET_WEBGL)
GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT,
#endif
};
if(value == 0)
@ -815,9 +868,9 @@ Debug operator<<(Debug debug, const Shader::Type value) {
#ifndef MAGNUM_TARGET_GLES
_c(TessellationControl)
_c(TessellationEvaluation)
_c(Geometry)
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(Geometry)
_c(Compute)
#endif
_c(Fragment)

44
src/Magnum/Shader.h

@ -83,17 +83,23 @@ class MAGNUM_EXPORT Shader: public AbstractObject {
* or WebGL.
*/
TessellationEvaluation = GL_TESS_EVALUATION_SHADER,
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* Geometry shader
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gl Geometry shaders are not available in OpenGL ES or
* WebGL.
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_es_extension Extension @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
#ifndef MAGNUM_TARGET_GLES
Geometry = GL_GEOMETRY_SHADER,
#else
Geometry = GL_GEOMETRY_SHADER_EXT,
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* Compute shader
* @requires_gl43 Extension @extension{ARB,compute_shader}
@ -181,16 +187,20 @@ class MAGNUM_EXPORT Shader: public AbstractObject {
* WebGL.
*/
static Int maxTessellationEvaluationOutputComponents();
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* @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} (part of
* OpenGL 3.2) is not available, returns `0`.
* OpenGL calls. If neither @extension{ARB,geometry_shader4} (part of
* OpenGL 3.2) nor @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader} ES extension is not available,
* returns `0`.
* @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_INPUT_COMPONENTS}
* @requires_gl Geometry shaders are not available in OpenGL ES or
* WebGL.
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles Geometry shaders are not available in WebGL.
*/
static Int maxGeometryInputComponents();
@ -198,11 +208,13 @@ class MAGNUM_EXPORT Shader: public AbstractObject {
* @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} (part of
* OpenGL 3.2) is not available, returns `0`.
* OpenGL calls. If neither @extension{ARB,geometry_shader4} (part of
* OpenGL 3.2) nor @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader} ES extension is not available,
* returns `0`.
* @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_OUTPUT_COMPONENTS}
* @requires_gl Geometry shaders are not available in OpenGL ES or
* WebGL.
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles Geometry shaders are not available in WebGL.
*/
static Int maxGeometryOutputComponents();
@ -210,11 +222,13 @@ class MAGNUM_EXPORT Shader: public AbstractObject {
* @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} (part of
* OpenGL 3.2) is not available, returns `0`.
* OpenGL calls. If neither @extension{ARB,geometry_shader4} (part of
* OpenGL 3.2) nor @es_extension{ANDROID,extension_pack_es31a}/
* @es_extension{EXT,geometry_shader} ES extension is not available,
* returns `0`.
* @see @fn_gl{Get} with @def_gl{MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS}
* @requires_gl Geometry shaders are not available in OpenGL ES or
* WebGL.
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles Geometry shaders are not available in WebGL.
*/
static Int maxGeometryTotalOutputComponents();
#endif

Loading…
Cancel
Save