Browse Source

GL: implemented missing Renderer::setPatch*() for tessellation shaders.

The last bits!
pull/388/merge
Vladimír Vondruš 6 years ago
parent
commit
cc401b2b3c
  1. 5
      doc/changelog.dox
  2. 4
      doc/opengl-mapping.dox
  3. 4
      doc/opengl-support.dox
  4. 17
      src/Magnum/GL/Implementation/RendererState.cpp
  5. 6
      src/Magnum/GL/Implementation/RendererState.h
  6. 34
      src/Magnum/GL/Renderer.cpp
  7. 63
      src/Magnum/GL/Renderer.h
  8. 26
      src/Magnum/GL/Test/RendererGLTest.cpp
  9. 1
      src/Magnum/Platform/gl-info.cpp

5
doc/changelog.dox

@ -57,6 +57,11 @@ See also:
@gl_extension{EXT,draw_buffers_indexed} ES extension and
@webgl_extension{EXT,draw_buffers_indexed} WebGL 2 extension in
@ref GL::Renderer
- Implemented @ref GL::Renderer::setPatchVertexCount(),
@ref GL::Renderer::setPatchDefaultInnerLevel() and
@ref GL::Renderer::setPatchDefaultOuterLevel() as the last missing bits for
@gl_extension{ARB,tessellation_shader} / @gl_extension{EXT,tessellation_shader}
support (see [mosra/magnum#164](https://github.com/mosra/magnum/issues/164))
- Recognizing @gl_extension{AMD,shader_explicit_vertex_parameter} desktop
and @gl_extension{NV,fragment_shader_barycentric} desktop / ES extensions.
These add only shading language features.

4
doc/opengl-mapping.dox

@ -309,7 +309,7 @@ OpenGL function | Matching API
OpenGL function | Matching API
--------------------------------------- | ------------
@fn_gl{PatchParameter} | |
@fn_gl{PatchParameter} | @ref GL::Renderer::setPatchVertexCount(), \n @ref GL::Renderer::setPatchDefaultInnerLevel(), \n @ref GL::Renderer::setPatchDefaultOuterLevel()
@fn_gl{PauseTransformFeedback}, @fn_gl{ResumeTransformFeedback} | @ref GL::TransformFeedback::pause(), @ref GL::TransformFeedback::resume()
@fn_gl{PixelStore} | @ref GL::Texture::setImage(), \n @ref GL::TextureArray::setImage(), \n @ref GL::CubeMapTexture::setImage(), \n @ref GL::CubeMapTextureArray::setImage(), \n @ref GL::RectangleTexture::setImage(), \n @ref GL::Texture::setSubImage(), \n @ref GL::TextureArray::setSubImage(), \n @ref GL::CubeMapTexture::setSubImage(), \n @ref GL::CubeMapTextureArray::setSubImage(), \n @ref GL::RectangleTexture::setSubImage(), \n @ref GL::Texture::image(), @ref GL::TextureArray::image(), \n @ref GL::CubeMapTexture::image(), \n @ref GL::CubeMapTextureArray::image(), \n @ref GL::RectangleTexture::image(), \n @ref GL::Texture::subImage(), \n @ref GL::TextureArray::subImage(), \n @ref GL::CubeMapTexture::subImage(), \n @ref GL::CubeMapTextureArray::subImage(), \n @ref GL::RectangleTexture::subImage(), \n @ref GL::Texture::setCompressedImage(), \n @ref GL::TextureArray::setCompressedImage(), \n @ref GL::CubeMapTexture::setCompressedImage(), \n @ref GL::CubeMapTextureArray::setCompressedImage(), \n @ref GL::Texture::setCompressedSubImage(), \n @ref GL::TextureArray::setCompressedSubImage(), \n @ref GL::CubeMapTexture::setCompressedSubImage(), \n @ref GL::CubeMapTextureArray::setCompressedSubImage(), \n @ref GL::RectangleTexture::setCompressedSubImage(), \n @ref GL::Texture::compressedImage(), \n @ref GL::TextureArray::compressedImage(), \n @ref GL::CubeMapTexture::compressedImage(), \n @ref GL::CubeMapTextureArray::compressedImage(), \n @ref GL::RectangleTexture::compressedImage(), \n @ref GL::DefaultFramebuffer::read(), \n @ref GL::Framebuffer::read()
@fn_gl{PointParameter} | |
@ -501,7 +501,7 @@ glGet() parameter | Matching API
@def_gl{MAX_IMAGE_SAMPLES} | @ref GL::AbstractShaderProgram::maxImageSamples()
@def_gl{MAX_IMAGE_UNITS} | @ref GL::AbstractShaderProgram::maxImageUnits()
@def_gl{MAX_LABEL_LENGTH} | @ref GL::AbstractObject::maxLabelLength()
@def_gl{MAX_PATCH_VERTICES} | |
@def_gl{MAX_PATCH_VERTICES} | @ref GL::Renderer::maxPatchVertexCount()
@def_gl{MAX_RENDERBUFFER_SIZE} | @ref GL::Renderbuffer::maxSize()
@def_gl{MAX_SAMPLE_MASK_WORDS} | |
@def_gl{MAX_SERVER_WAIT_TIMEOUT} | |

4
doc/opengl-support.dox

@ -149,7 +149,7 @@ GLSL 4.00 | done
@gl_extension{ARB,gpu_shader5} | missing limit queries
@gl_extension{ARB,gpu_shader_fp64} | done
@gl_extension{ARB,shader_subroutine} | |
@gl_extension{ARB,tessellation_shader} | missing some limit queries and patch parameter specification function
@gl_extension{ARB,tessellation_shader} | done except for `MAX_TESS_GEN_LEVEL` and `MAX_TESS_PATCH_COMPONENTS` queries
@gl_extension{ARB,texture_buffer_object_rgb32} | done
@gl_extension{ARB,transform_feedback2} | done
@gl_extension{ARB,transform_feedback3} | missing indexed properties query
@ -358,7 +358,7 @@ Extension | Status
@gl_extension{EXT,geometry_shader} | missing some ES-specific limit queries
@gl_extension{EXT,gpu_shader5} | done (shading language only)
@gl_extension{EXT,shader_io_blocks} | done (shading language only)
@gl_extension{EXT,tessellation_shader} | see above
@gl_extension{EXT,tessellation_shader} | done except for `MAX_TESS_GEN_LEVEL` and `MAX_TESS_PATCH_COMPONENTS` queries
@gl_extension{EXT,texture_border_clamp} | done
@gl_extension{EXT,texture_buffer} | done
@gl_extension{EXT,texture_cube_map_array} | done

17
src/Magnum/GL/Implementation/RendererState.cpp

@ -107,6 +107,23 @@ RendererState::RendererState(Context& context, ContextState& contextState, std::
minSampleShadingImplementation = nullptr;
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
#ifdef MAGNUM_TARGET_GLES
if(context.isVersionSupported(Version::GLES320))
#endif
{
patchParameteriImplementation = glPatchParameteri;
}
#ifdef MAGNUM_TARGET_GLES
else {
/* Not checking for the extension (nor adding it to the extension list)
as this is not any optional feature -- it can be only used when
the extension is present, and if it's not, the pointers are null */
patchParameteriImplementation = glPatchParameteriEXT;
}
#endif
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
#ifdef MAGNUM_TARGET_GLES

6
src/Magnum/GL/Implementation/RendererState.h

@ -43,6 +43,9 @@ struct RendererState {
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void(*minSampleShadingImplementation)(GLfloat);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void (*patchParameteriImplementation)(GLenum, GLint);
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void(*enableiImplementation)(GLenum, GLuint);
void(*disableiImplementation)(GLenum, GLuint);
@ -85,6 +88,9 @@ struct RendererState {
PixelStorage packPixelStorage, unpackPixelStorage;
Range1D lineWidthRange;
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
GLint maxPatchVertexCount{};
#endif
/* Bool parameter is ugly, but this is implementation detail of internal
API so who cares */

34
src/Magnum/GL/Renderer.cpp

@ -163,6 +163,40 @@ void Renderer::minSampleShadingImplementationOES(const GLfloat value) {
#endif
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
UnsignedInt Renderer::maxPatchVertexCount() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::ARB::tessellation_shader>())
return 0;
#else
if(!Context::current().isExtensionSupported<Extensions::EXT::tessellation_shader>())
return 0;
#endif
GLint& value = Context::current().state().renderer->maxPatchVertexCount;
/* Get the value, if not already cached */
if(value == 0)
glGetIntegerv(GL_MAX_PATCH_VERTICES, &value);
return value;
}
void Renderer::setPatchVertexCount(UnsignedInt count) {
Context::current().state().renderer->patchParameteriImplementation(GL_PATCH_VERTICES, count);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void Renderer::setPatchDefaultInnerLevel(const Vector2& levels) {
glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, levels.data());
}
void Renderer::setPatchDefaultOuterLevel(const Vector4& levels) {
glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, levels.data());
}
#endif
void Renderer::setScissor(const Range2Di& rectangle) {
glScissor(rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY());
}

63
src/Magnum/GL/Renderer.h

@ -685,6 +685,69 @@ class MAGNUM_GL_EXPORT Renderer {
static void setMinSampleShading(Float value);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* @brief Max supported component patch vertex count
* @m_since_latest
*
* The result is cached, repeated queries don't result in repeated
* OpenGL calls. If neither @gl_extension{ARB,tessellation_shader} (part
* of OpenGL 4.0) nor @gl_extension{ANDROID,extension_pack_es31a} /
* @gl_extension{EXT,tessellation_shader} ES extension is available,
* returns @cpp 0 @ce.
* @see @fn_gl{Get} with @def_gl_keyword{MAX_PATCH_VERTICES}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles Tessellation shaders are not available in WebGL.
*/
static UnsignedInt maxPatchVertexCount();
/**
* @brief Set tessellation patch vertex count
* @m_since_latest
*
* Specifies number of vertices that will be used to make up a single
* tessellation patch primitive.
* @see @ref maxPatchVertexCount(),
* @fn_gl_keyword{PatchParameter} with @def_gl{PATCH_VERTICES}
* @requires_gl40 Extension @gl_extension{ARB,tessellation_shader}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles32 Extension @gl_extension{ANDROID,extension_pack_es31a} /
* @gl_extension{EXT,tessellation_shader}
* @requires_gles Tessellation shaders are not available in WebGL.
*/
static void setPatchVertexCount(UnsignedInt count);
#endif
#ifndef MAGNUM_TARGET_GLES
/**
* @brief Set default patch inner tessellation level
* @m_since_latest
*
* When no tessellation control shader is present, specifies the
* default inner tessellation levels to be used.
* @see @fn_gl_keyword{PatchParameter} with
* @def_gl{PATCH_DEFAULT_INNER_LEVEL}
* @requires_gl40 Extension @gl_extension{ARB,tessellation_shader}
* @requires_gl A tessellation control shader has to be always present
* in OpenGL ES.
*/
static void setPatchDefaultInnerLevel(const Vector2& levels);
/**
* @brief Set default patch outer tessellation level
* @m_since_latest
*
* When no tessellation control shader is present, specifies the
* default outer tessellation levels to be used.
* @see @fn_gl_keyword{PatchParameter} with
* @def_gl{PATCH_DEFAULT_OUTER_LEVEL}
* @requires_gl40 Extension @gl_extension{ARB,tessellation_shader}
* @requires_gl A tessellation control shader has to be always present
* in OpenGL ES.
*/
static void setPatchDefaultOuterLevel(const Vector4& levels);
#endif
/*@}*/
/** @{ @name Scissor operations */

26
src/Magnum/GL/Test/RendererGLTest.cpp

@ -55,6 +55,9 @@ struct RendererGLTest: OpenGLTester {
void maxLineWidth();
void pointCoord();
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void patchParameters();
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void drawBuffersIndexed();
void drawBuffersBlend();
@ -73,6 +76,9 @@ using namespace Math::Literals;
RendererGLTest::RendererGLTest() {
addTests({&RendererGLTest::maxLineWidth,
&RendererGLTest::pointCoord,
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
&RendererGLTest::patchParameters,
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
&RendererGLTest::drawBuffersIndexed,
&RendererGLTest::drawBuffersBlend
@ -230,6 +236,26 @@ void RendererGLTest::pointCoord() {
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
}
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void RendererGLTest::patchParameters() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::ARB::tessellation_shader>())
CORRADE_SKIP(Extensions::ARB::tessellation_shader::string() + std::string(" is not available."));
#else
if(!Context::current().isExtensionSupported<Extensions::EXT::tessellation_shader>())
CORRADE_SKIP(Extensions::EXT::tessellation_shader::string() + std::string(" is not available."));
#endif
/* All we can do is check for GL errors */
Renderer::setPatchVertexCount(Renderer::maxPatchVertexCount());
#ifndef MAGNUM_TARGET_GLES
Renderer::setPatchDefaultInnerLevel({0.3f, 1.2f});
Renderer::setPatchDefaultOuterLevel({0.3f, 2.2f, 1.0f, 1.2f});
#endif
MAGNUM_VERIFY_NO_GL_ERROR();
}
#endif
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
void RendererGLTest::drawBuffersIndexed() {
#ifndef MAGNUM_TARGET_GLES

1
src/Magnum/Platform/gl-info.cpp

@ -710,6 +710,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
_l(GL::Shader::maxTessellationControlTotalOutputComponents())
_l(GL::Shader::maxTessellationEvaluationInputComponents())
_l(GL::Shader::maxTessellationEvaluationOutputComponents())
_l(GL::Renderer::maxPatchVertexCount())
}
#endif

Loading…
Cancel
Save