Browse Source

Full ARB_direct_state_access support in framebuffers.

In comparison to EXT_DSA, ARB_DSA also knows how to blit and invalidate
without binding, yay!
pull/77/head
Vladimír Vondruš 12 years ago
parent
commit
dca670eb70
  1. 59
      src/Magnum/AbstractFramebuffer.cpp
  2. 52
      src/Magnum/AbstractFramebuffer.h
  3. 75
      src/Magnum/DefaultFramebuffer.h
  4. 16
      src/Magnum/Framebuffer.cpp
  5. 141
      src/Magnum/Framebuffer.h
  6. 49
      src/Magnum/Implementation/FramebufferState.cpp
  7. 4
      src/Magnum/Implementation/FramebufferState.h
  8. 8
      src/Magnum/Renderbuffer.cpp
  9. 33
      src/Magnum/Renderbuffer.h

59
src/Magnum/AbstractFramebuffer.cpp

@ -144,21 +144,32 @@ FramebufferTarget AbstractFramebuffer::bindInternal() {
#endif
}
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter) {
void AbstractFramebuffer::blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
Context::current()->state().framebuffer->blitImplementation(source, destination, sourceRectangle, destinationRectangle, mask, filter);
}
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::blitImplementationDefault(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw);
#ifndef MAGNUM_TARGET_GLES2
glBlitFramebuffer(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter));
#else
Context::current()->state().framebuffer->blitImplementation(sourceRectangle, destinationRectangle, mask, filter);
#endif
}
#ifdef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::blitImplementationANGLE(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::blitImplementationDSA(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
glBlitNamedFramebuffer(source._id, destination._id, sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter));
}
#endif
#else
void AbstractFramebuffer::blitImplementationANGLE(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw);
glBlitFramebufferANGLE(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter));
#else
static_cast<void>(source);
static_cast<void>(destination);
static_cast<void>(sourceRectangle);
static_cast<void>(destinationRectangle);
static_cast<void>(mask);
@ -167,10 +178,14 @@ void AbstractFramebuffer::blitImplementationANGLE(const Range2Di& sourceRectangl
#endif
}
void AbstractFramebuffer::blitImplementationNV(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
void AbstractFramebuffer::blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, const FramebufferBlitMask mask, const FramebufferBlitFilter filter) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
source.bindInternal(FramebufferTarget::Read);
destination.bindInternal(FramebufferTarget::Draw);
glBlitFramebufferNV(sourceRectangle.left(), sourceRectangle.bottom(), sourceRectangle.right(), sourceRectangle.top(), destinationRectangle.left(), destinationRectangle.bottom(), destinationRectangle.right(), destinationRectangle.top(), GLbitfield(mask), GLenum(filter));
#else
static_cast<void>(source);
static_cast<void>(destination);
static_cast<void>(sourceRectangle);
static_cast<void>(destinationRectangle);
static_cast<void>(mask);
@ -256,12 +271,24 @@ void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, c
#endif
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::invalidateImplementationDSA(const GLsizei count, const GLenum* const attachments) {
glInvalidateNamedFramebufferData(_id, count, attachments);
}
#endif
#ifndef MAGNUM_TARGET_GLES2
void AbstractFramebuffer::invalidateImplementationNoOp(GLsizei, const GLenum*, const Range2Di&) {}
void AbstractFramebuffer::invalidateImplementationDefault(const GLsizei count, const GLenum* const attachments, const Range2Di& rectangle) {
glInvalidateSubFramebuffer(GLenum(bindInternal()), count, attachments, rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY());
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::invalidateImplementationDSA(const GLsizei count, const GLenum* const attachments, const Range2Di& rectangle) {
glInvalidateNamedFramebufferSubData(_id, count, attachments, rectangle.left(), rectangle.bottom(), rectangle.sizeX(), rectangle.sizeY());
}
#endif
#endif
GLenum AbstractFramebuffer::checkStatusImplementationDefault(const FramebufferTarget target) {
@ -270,6 +297,10 @@ GLenum AbstractFramebuffer::checkStatusImplementationDefault(const FramebufferTa
}
#ifndef MAGNUM_TARGET_GLES
GLenum AbstractFramebuffer::checkStatusImplementationDSA(const FramebufferTarget target) {
return glCheckNamedFramebufferStatus(_id, GLenum(target));
}
GLenum AbstractFramebuffer::checkStatusImplementationDSAEXT(const FramebufferTarget target) {
_created = true;
return glCheckNamedFramebufferStatusEXT(_id, GLenum(target));
@ -295,6 +326,10 @@ void AbstractFramebuffer::drawBuffersImplementationDefault(GLsizei count, const
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::drawBuffersImplementationDSA(const GLsizei count, const GLenum* const buffers) {
glNamedFramebufferDrawBuffers(_id, count, buffers);
}
void AbstractFramebuffer::drawBuffersImplementationDSAEXT(GLsizei count, const GLenum* buffers) {
_created = true;
glFramebufferDrawBuffersEXT(_id, count, buffers);
@ -321,6 +356,10 @@ void AbstractFramebuffer::drawBufferImplementationDefault(GLenum buffer) {
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::drawBufferImplementationDSA(const GLenum buffer) {
glNamedFramebufferDrawBuffer(_id, buffer);
}
void AbstractFramebuffer::drawBufferImplementationDSAEXT(GLenum buffer) {
_created = true;
glFramebufferDrawBufferEXT(_id, buffer);
@ -345,6 +384,10 @@ void AbstractFramebuffer::readBufferImplementationDefault(GLenum buffer) {
}
#ifndef MAGNUM_TARGET_GLES
void AbstractFramebuffer::readBufferImplementationDSA(const GLenum buffer) {
glFramebufferReadBufferEXT(_id, buffer);
}
void AbstractFramebuffer::readBufferImplementationDSAEXT(GLenum buffer) {
_created = true;
glFramebufferReadBufferEXT(_id, buffer);

52
src/Magnum/AbstractFramebuffer.h

@ -169,6 +169,10 @@ switching framebuffers. Framebuffer limits and implementation-defined values
(such as @ref maxViewportSize()) are cached, so repeated queries don't result
in repeated @fn_gl{Get} calls.
If extension @extension{ARB,direct_state_access} (part of OpenGL 4.5) is
available, @ref blit() function uses DSA to avoid unnecessary call to
@fn_gl{BindFramebuffer}. See its documentation for more information.
If @extension{ARB,robustness} is available, @ref read() operations are
protected from buffer overflow.
*/
@ -222,13 +226,15 @@ class MAGNUM_EXPORT AbstractFramebuffer {
* @param mask Which buffers to perform blit operation on
* @param filter Interpolation filter
*
* Binds @p source framebuffer to @ref FramebufferTarget::Read and
* @p destination framebuffer to @ref FramebufferTarget::Draw and
* performs blitting operation. See @ref DefaultFramebuffer::mapForRead(),
* @ref Framebuffer::mapForRead(), @ref DefaultFramebuffer::mapForDraw()
* and @ref Framebuffer::mapForDraw() for specifying particular buffers
* for blitting operation.
* @see @fn_gl{BlitFramebuffer}
* See @ref DefaultFramebuffer::mapForRead(), @ref Framebuffer::mapForRead(),
* @ref DefaultFramebuffer::mapForDraw() and @ref Framebuffer::mapForDraw()
* for specifying particular buffers for blitting operation. If
* @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, @p source framebuffer is bound to @ref FramebufferTarget::Read
* and @p destination framebuffer to @ref FramebufferTarget::Draw
* before the operation (if not already).
* @see @fn_gl2{BlitNamedFramebuffer,BlitFramebuffer}, eventually
* @fn_gl{BlitFramebuffer}
* @requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0
* @todo NaCl exports `BlitFramebufferEXT` (although no such extension
@ -238,18 +244,11 @@ class MAGNUM_EXPORT AbstractFramebuffer {
/**
* @brief Copy block of pixels
* @param source Source framebuffer
* @param destination Destination framebuffer
* @param rectangle Source and destination rectangle
* @param mask Which buffers to perform blit operation on
*
* Convenience alternative to above function when source rectangle is
* the same as destination rectangle. As the image is copied
* Convenience alternative to the above function when source rectangle
* is the same as destination rectangle. As the image is copied
* pixel-by-pixel, no interpolation is needed and thus
* @ref FramebufferBlitFilter::Nearest filtering is used by default.
* @see @fn_gl{BlitFramebuffer}
* @requires_gles30 Extension @es_extension{ANGLE,framebuffer_blit} or
* @es_extension{NV,framebuffer_blit} in OpenGL ES 2.0
*/
static void blit(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& rectangle, FramebufferBlitMask mask) {
blit(source, destination, rectangle, rectangle, mask, FramebufferBlitFilter::Nearest);
@ -348,28 +347,37 @@ class MAGNUM_EXPORT AbstractFramebuffer {
Range2Di _viewport;
private:
#ifdef MAGNUM_TARGET_GLES2
static void MAGNUM_LOCAL blitImplementationANGLE(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
static void MAGNUM_LOCAL blitImplementationNV(const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
#ifndef MAGNUM_TARGET_GLES2
static void MAGNUM_LOCAL blitImplementationDefault(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
#ifndef MAGNUM_TARGET_GLES
static void MAGNUM_LOCAL blitImplementationDSA(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
#endif
#else
static void MAGNUM_LOCAL blitImplementationANGLE(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
static void MAGNUM_LOCAL blitImplementationNV(AbstractFramebuffer& source, AbstractFramebuffer& destination, const Range2Di& sourceRectangle, const Range2Di& destinationRectangle, FramebufferBlitMask mask, FramebufferBlitFilter filter);
#endif
GLenum MAGNUM_LOCAL checkStatusImplementationDefault(FramebufferTarget target);
#ifndef MAGNUM_TARGET_GLES
GLenum MAGNUM_LOCAL checkStatusImplementationDSA(FramebufferTarget target);
GLenum MAGNUM_LOCAL checkStatusImplementationDSAEXT(FramebufferTarget target);
#endif
void MAGNUM_LOCAL drawBuffersImplementationDefault(GLsizei count, const GLenum* buffers);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL drawBuffersImplementationDSA(GLsizei count, const GLenum* buffers);
void MAGNUM_LOCAL drawBuffersImplementationDSAEXT(GLsizei count, const GLenum* buffers);
#endif
void MAGNUM_LOCAL drawBufferImplementationDefault(GLenum buffer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL drawBufferImplementationDSA(GLenum buffer);
void MAGNUM_LOCAL drawBufferImplementationDSAEXT(GLenum buffer);
#endif
void MAGNUM_LOCAL readBufferImplementationDefault(GLenum buffer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL readBufferImplementationDSA(GLenum buffer);
void MAGNUM_LOCAL readBufferImplementationDSAEXT(GLenum buffer);
#endif
@ -378,10 +386,16 @@ class MAGNUM_EXPORT AbstractFramebuffer {
void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*);
void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateImplementationDSA(GLsizei count, const GLenum* attachments);
#endif
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL invalidateImplementationNoOp(GLsizei, const GLenum*, const Range2Di&);
void MAGNUM_LOCAL invalidateImplementationDefault(GLsizei count, const GLenum* attachments, const Range2Di& rectangle);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL invalidateImplementationDSA(GLsizei count, const GLenum* attachments, const Range2Di& rectangle);
#endif
#endif
};

75
src/Magnum/DefaultFramebuffer.h

@ -74,10 +74,11 @@ multiple framebuffers.
See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer".
If extension @extension{EXT,direct_state_access} is available, functions
@ref mapForDraw() and @ref mapForRead() use DSA to avoid unnecessary calls to
@fn_gl{BindFramebuffer}. See their respective documentation for more
information.
If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL
4.5) or @extension{EXT,direct_state_access} is available, functions
@ref checkStatus(), @ref mapForDraw(), @ref mapForRead() and @ref invalidate()
use DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}. See their
respective documentation for more information.
*/
class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
friend class Context;
@ -315,11 +316,12 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @brief Check framebuffer status
* @param target Target for which to check the status
*
* If @extension{EXT,direct_state_access} is not available and the
* framebuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl{CheckFramebufferStatus} or
* @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @fn_gl2{CheckNamedFramebufferStatus,CheckFramebufferStatus},
* @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{CheckFramebufferStatus}
* @requires_gl30 Extension @extension{ARB,framebuffer_object}
*/
Status checkStatus(FramebufferTarget target);
@ -334,16 +336,17 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* can achieve the same by passing @ref DrawAttachment::None as
* attachment. Example usage:
* @code
* framebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft},
* {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}});
* defaultFramebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::BackLeft},
* {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}});
* @endcode
*
* If @extension{EXT,direct_state_access} is not available and the
* framebuffer is not currently bound, it is bound before the
* operation.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref maxDrawBuffers(), @ref maxDualSourceDrawBuffers(),
* @ref mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers}
* or @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}
* @ref mapForRead(), @fn_gl2{NamedFramebufferDrawBuffers,DrawBuffers},
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffers}
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
*/
@ -357,11 +360,12 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
*
* If @extension{EXT,direct_state_access} is not available and the
* framebuffer is not currently bound, it is bound before the
* operation.
* @see @ref mapForRead(), @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer}
* or @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access},
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref mapForRead(), @fn_gl2{NamedFramebufferDrawBuffer,DrawBuffer},
* @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffer} or
* @fn_gl{DrawBuffers} in OpenGL ES 3.0
* @requires_gles30 Draw attachments for default framebuffer are
* available only in OpenGL ES 3.0.
@ -374,11 +378,12 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @param attachment Buffer attachment
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebuffer is not currently bound, it is bound before the
* operation.
* @see mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer} or
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref mapForDraw(), @fn_gl2{NamedFramebufferReadBuffer,ReadBuffer},
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{ReadBuffer}
* @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
* in OpenGL ES 2.0
*/
@ -391,9 +396,12 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3), extension @es_extension{EXT,discard_framebuffer} in OpenGL ES
* 2.0 or OpenGL ES 3.0 is not available, this function does nothing.
* The framebuffer is bound to some target before the operation, if not
* already.
* @see @fn_gl{InvalidateFramebuffer} or @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* If @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, the framebuffer is bound before the operation (if not
* already).
* @see @fn_gl2{InvalidateNamedFramebufferData,InvalidateFramebuffer},
* eventually @fn_gl{InvalidateFramebuffer} or
* @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* on OpenGL ES 2.0
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
@ -405,10 +413,13 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer {
* @param rectangle Rectangle to invalidate
*
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3) is not available, this function does nothing. The framebuffer
* is bound to some target before the operation, if not already.
* 4.3) is not available, this function does nothing. If
* @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref invalidate(std::initializer_list<InvalidationAttachment>),
* @fn_gl{InvalidateSubFramebuffer}
* @fn_gl2{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer},
* eventually @fn_gl{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref Magnum::DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment>) "invalidate(std::initializer_list<InvalidationAttachment>)"
* in OpenGL ES 2.0 instead.
*/

16
src/Magnum/Framebuffer.cpp

@ -267,6 +267,10 @@ void Framebuffer::renderbufferImplementationDefault(BufferAttachment attachment,
}
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::renderbufferImplementationDSA(const BufferAttachment attachment, Renderbuffer& renderbuffer) {
glNamedFramebufferRenderbuffer(_id, GLenum(attachment), GL_RENDERBUFFER, renderbuffer.id());
}
void Framebuffer::renderbufferImplementationDSAEXT(BufferAttachment attachment, Renderbuffer& renderbuffer) {
_created = true;
glNamedFramebufferRenderbufferEXT(_id, GLenum(attachment), GL_RENDERBUFFER, renderbuffer.id());
@ -276,6 +280,10 @@ void Framebuffer::texture1DImplementationDefault(BufferAttachment attachment, GL
glFramebufferTexture1D(GLenum(bindInternal()), GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel);
}
void Framebuffer::texture1DImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel) {
glNamedFramebufferTexture(_id, GLenum(attachment), textureId, mipLevel);
}
void Framebuffer::texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel) {
_created = true;
glNamedFramebufferTexture1DEXT(_id, GLenum(attachment), GL_TEXTURE_1D, textureId, mipLevel);
@ -287,6 +295,10 @@ void Framebuffer::texture2DImplementationDefault(BufferAttachment attachment, GL
}
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::texture2DImplementationDSA(const BufferAttachment attachment, GLenum, const GLuint textureId, const GLint mipLevel) {
glNamedFramebufferTexture(_id, GLenum(attachment), textureId, mipLevel);
}
void Framebuffer::texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint mipLevel) {
_created = true;
glNamedFramebufferTexture2DEXT(_id, GLenum(attachment), textureTarget, textureId, mipLevel);
@ -308,6 +320,10 @@ void Framebuffer::textureLayerImplementationDefault(BufferAttachment attachment,
}
#ifndef MAGNUM_TARGET_GLES
void Framebuffer::textureLayerImplementationDSA(const BufferAttachment attachment, const GLuint textureId, const GLint mipLevel, const GLint layer) {
glNamedFramebufferTextureLayer(_id, GLenum(attachment), textureId, mipLevel, layer);
}
void Framebuffer::textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint mipLevel, GLint layer) {
_created = true;
glNamedFramebufferTextureLayerEXT(_id, GLenum(attachment), textureId, mipLevel, layer);

141
src/Magnum/Framebuffer.h

@ -93,11 +93,13 @@ void drawEvent() {
See also @ref AbstractFramebuffer-performance-optimization "relevant section in AbstractFramebuffer".
If extension @extension{EXT,direct_state_access} is available, functions
@ref mapForDraw(), @ref mapForRead(), @ref attachRenderbuffer(),
@ref attachTexture1D(), @ref attachTexture2D(), @ref attachCubeMapTexture() and
@ref attachTexture3D() use DSA to avoid unnecessary calls to @fn_gl{BindFramebuffer}.
See their respective documentation for more information.
If on desktop GL and either @extension{ARB,direct_state_access} (part of OpenGL
4.5) or @extension{EXT,direct_state_access} is available, functions
@ref checkStatus(), @ref mapForDraw(), @ref mapForRead(), @ref invalidate(),
@ref attachRenderbuffer(), @ref attachTexture(), @ref attachCubeMapTexture()
and @ref attachTextureLayer() use DSA to avoid unnecessary calls to
@fn_gl{BindFramebuffer}. See their respective documentation for more
information.
@requires_gl30 Extension @extension{ARB,framebuffer_object}
@todo `MAX_COLOR_ATTACHMENTS`
@ -370,11 +372,12 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @brief Check framebuffer status
* @param target Target for which check the status
*
* If @extension{EXT,direct_state_access} is not available and the
* framebuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl{CheckFramebufferStatus} or
* @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @fn_gl2{CheckNamedFramebufferStatus,CheckFramebufferStatus},
* @fn_gl_extension{CheckNamedFramebufferStatus,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{CheckFramebufferStatus}
*/
Status checkStatus(FramebufferTarget target);
@ -391,13 +394,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* {MyShader::NormalOutput, Framebuffer::DrawAttachment::None}});
* @endcode
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref maxDrawBuffers(), @ref maxDualSourceDrawBuffers(),
* @ref maxColorAttachments(), @ref mapForRead(),
* @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffers} or
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access}
* @fn_gl2{NamedFramebufferDrawBuffers,DrawBuffers},
* @fn_gl_extension{FramebufferDrawBuffers,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffers}
* @requires_gles30 Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
* in OpenGL ES 2.0
*/
@ -411,12 +415,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* Similar to above function, can be used in cases when shader has
* only one (unnamed) output.
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref maxColorAttachments(), @ref mapForRead(),
* @fn_gl{BindFramebuffer}, @fn_gl{DrawBuffer} or
* @fn_gl2{NamedFramebufferDrawBuffer,DrawBuffer},
* @fn_gl_extension{FramebufferDrawBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{DrawBuffer} or
* @fn_gl{DrawBuffers} in OpenGL ES 3.0
* @requires_gles30 Extension @es_extension2{NV,draw_buffers,GL_NV_draw_buffers}
* in OpenGL ES 2.0
@ -428,11 +433,12 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param attachment Color attachment
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @ref mapForDraw(), @fn_gl{BindFramebuffer}, @fn_gl{ReadBuffer}
* or @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref mapForDraw(), @fn_gl2{NamedFramebufferReadBuffer,ReadBuffer},
* @fn_gl_extension{FramebufferReadBuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{ReadBuffer}
* @requires_gles30 Extension @es_extension2{NV,read_buffer,GL_NV_read_buffer}
* in OpenGL ES 2.0
*/
@ -445,9 +451,12 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3), extension @es_extension{EXT,discard_framebuffer} in OpenGL ES
* 2.0 or OpenGL ES 3.0 is not available, this function does nothing.
* The framebuffer is bound to some target before the operation, if not
* already.
* @see @fn_gl{InvalidateFramebuffer} or @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* If @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, the framebuffer is bound before the operation (if not
* already).
* @see @fn_gl2{InvalidateNamedFramebufferData,InvalidateFramebuffer},
* eventually @fn_gl{InvalidateFramebuffer} or
* @fn_gles_extension{DiscardFramebuffer,EXT,discard_framebuffer}
* on OpenGL ES 2.0
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments);
@ -459,11 +468,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param rectangle Rectangle to invalidate
*
* If extension @extension{ARB,invalidate_subdata} (part of OpenGL
* 4.3) is not available, this function does nothing. The framebuffer
* is bound to some target before the operation, if not already.
* 4.3) is not available, this function does nothing. If
* @extension{ARB,direct_state_access} (part of OpenGL 4.5) is not
* available, the framebuffer is bound before the operation (if not
* already).
* @see @ref invalidate(std::initializer_list<InvalidationAttachment>),
* @fn_gl{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref Magnum::Framebuffer::invalidate(std::initializer_list<InvalidationAttachment>) "invalidate(std::initializer_list<InvalidationAttachment>)"
* @fn_gl2{InvalidateNamedFramebufferSubData,InvalidateSubFramebuffer},
* eventually @fn_gl{InvalidateSubFramebuffer}
* @requires_gles30 Use @ref Magnum::DefaultFramebuffer::invalidate(std::initializer_list<InvalidationAttachment>) "invalidate(std::initializer_list<InvalidationAttachment>)"
* in OpenGL ES 2.0 instead.
*/
void invalidate(std::initializer_list<InvalidationAttachment> attachments, const Range2Di& rectangle);
@ -475,11 +487,12 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param renderbuffer Renderbuffer
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl{FramebufferRenderbuffer} or
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @fn_gl2{NamedFramebufferRenderbuffer,FramebufferRenderbuffer},
* @fn_gl_extension{NamedFramebufferRenderbuffer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl{FramebufferRenderbuffer}
*/
Framebuffer& attachRenderbuffer(BufferAttachment attachment, Renderbuffer& renderbuffer);
@ -491,12 +504,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param level Mip level
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @ref attachCubeMapTexture(), @fn_gl{BindFramebuffer},
* @fn_gl2{FramebufferTexture1D,FramebufferTexture} or
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref attachCubeMapTexture(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture1D,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and
* @fn_gl2{FramebufferTexture1D,FramebufferTexture}
* @requires_gl Only 2D and 3D textures are available in OpenGL ES.
*/
Framebuffer& attachTexture(BufferAttachment attachment, Texture1D& texture, Int level);
@ -509,12 +523,13 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param level Mip level
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @ref attachCubeMapTexture(), @fn_gl{BindFramebuffer},
* @fn_gl2{FramebufferTexture2D,FramebufferTexture} or
* @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref attachCubeMapTexture(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and
* @fn_gl2{FramebufferTexture2D,FramebufferTexture}
*/
Framebuffer& attachTexture(BufferAttachment attachment, Texture2D& texture, Int level);
@ -543,12 +558,12 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param level Mip level
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @ref attachTexture2D(), @fn_gl{BindFramebuffer},
* @fn_gl2{FramebufferTexture2D,FramebufferTexture} or
* @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @ref attachTexture2D(), @fn_gl2{NamedFramebufferTexture,FramebufferTexture},
* @fn_gl_extension{NamedFramebufferTexture2D,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl2{FramebufferTexture2D,FramebufferTexture}
*/
Framebuffer& attachCubeMapTexture(BufferAttachment attachment, CubeMapTexture& texture, CubeMapTexture::Coordinate coordinate, Int level);
@ -560,12 +575,14 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
* @param layer Layer
* @return Reference to self (for method chaining)
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @fn_gl{BindFramebuffer}, @fn_gl2{FramebufferTextureLayer,FramebufferTexture}
* or @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access},
* @fn_gles_extension{FramebufferTexture3D,OES,texture_3D} in OpenGL ES 2.0
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the framebuffer is bound before the operation (if not already).
* @see @fn_gl2{NamedFramebufferTextureLayer,FramebufferTextureLayer},
* @fn_gl_extension{NamedFramebufferTextureLayer,EXT,direct_state_access},
* eventually @fn_gl{BindFramebuffer} and @fn_gl2{FramebufferTextureLayer,FramebufferTexture}
* or @fn_gles_extension{FramebufferTexture3D,OES,texture_3D} in
* OpenGL ES 2.0
* @requires_gles30 Extension @es_extension{OES,texture_3D} in OpenGL
* ES 2.0
*/
@ -645,21 +662,25 @@ class MAGNUM_EXPORT Framebuffer: public AbstractFramebuffer, public AbstractObje
void MAGNUM_LOCAL renderbufferImplementationDefault(BufferAttachment attachment, Renderbuffer& renderbuffer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL renderbufferImplementationDSA(BufferAttachment attachment, Renderbuffer& renderbuffer);
void MAGNUM_LOCAL renderbufferImplementationDSAEXT(BufferAttachment attachment, Renderbuffer& renderbuffer);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL texture1DImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level);
void MAGNUM_LOCAL texture1DImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level);
void MAGNUM_LOCAL texture1DImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level);
#endif
void MAGNUM_LOCAL texture2DImplementationDefault(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL texture2DImplementationDSA(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
void MAGNUM_LOCAL texture2DImplementationDSAEXT(BufferAttachment attachment, GLenum textureTarget, GLuint textureId, GLint level);
#endif
void MAGNUM_LOCAL textureLayerImplementationDefault(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL textureLayerImplementationDSA(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
void MAGNUM_LOCAL textureLayerImplementationDSAEXT(BufferAttachment attachment, GLuint textureId, GLint level, GLint layer);
#endif
};

49
src/Magnum/Implementation/FramebufferState.cpp

@ -54,7 +54,22 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* DSA/non-DSA implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
/* Extension added above */
checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSA;
drawBuffersImplementation = &AbstractFramebuffer::drawBuffersImplementationDSA;
drawBufferImplementation = &AbstractFramebuffer::drawBufferImplementationDSA;
readBufferImplementation = &AbstractFramebuffer::readBufferImplementationDSA;
renderbufferImplementation = &Framebuffer::renderbufferImplementationDSA;
texture1DImplementation = &Framebuffer::texture1DImplementationDSA;
texture2DImplementation = &Framebuffer::texture2DImplementationDSA;
textureLayerImplementation = &Framebuffer::textureLayerImplementationDSA;
renderbufferStorageImplementation = &Renderbuffer::storageImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
extensions.push_back(Extensions::GL::EXT::direct_state_access::string());
checkStatusImplementation = &AbstractFramebuffer::checkStatusImplementationDSAEXT;
@ -131,7 +146,12 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
/* Multisample renderbuffer storage implementation */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
/* Extension added above */
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSA;
} else if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
/* Extension added above */
renderbufferStorageMultisampleImplementation = &Renderbuffer::storageMultisampleImplementationDSAEXT;
@ -158,8 +178,15 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
if(context.isExtensionSupported<Extensions::GL::ARB::invalidate_subdata>()) {
extensions.push_back(Extensions::GL::ARB::invalidate_subdata::string());
invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
/* Extension added above */
invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDSA;
invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDSA;
} else {
invalidateImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
}
} else {
invalidateImplementation = &AbstractFramebuffer::invalidateImplementationNoOp;
invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationNoOp;
@ -181,8 +208,16 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
invalidateSubImplementation = &AbstractFramebuffer::invalidateImplementationDefault;
#endif
/* Blit implementation on desktop GL */
#ifndef MAGNUM_TARGET_GLES
if(context.isExtensionSupported<Extensions::GL::ARB::direct_state_access>()) {
/* Extension added above */
blitImplementation = &AbstractFramebuffer::blitImplementationDSA;
} else blitImplementation = &AbstractFramebuffer::blitImplementationDefault;
/* Blit implementation on ES2 */
#ifdef MAGNUM_TARGET_GLES2
#elif defined(MAGNUM_TARGET_GLES2)
if(context.isExtensionSupported<Extensions::GL::ANGLE::framebuffer_blit>()) {
extensions.push_back(Extensions::GL::ANGLE::framebuffer_blit::string());
blitImplementation = &AbstractFramebuffer::blitImplementationANGLE;
@ -192,6 +227,10 @@ FramebufferState::FramebufferState(Context& context, std::vector<std::string>& e
blitImplementation = &AbstractFramebuffer::blitImplementationNV;
} else blitImplementation = nullptr;
/* Always available on ES3 */
#else
blitImplementation = &AbstractFramebuffer::blitImplementationDefault;
#endif
}

4
src/Magnum/Implementation/FramebufferState.h

@ -37,9 +37,7 @@ struct FramebufferState {
void reset();
#ifdef MAGNUM_TARGET_GLES2
void(*blitImplementation)(const Range2Di&, const Range2Di&, FramebufferBlitMask, FramebufferBlitFilter);
#endif
void(*blitImplementation)(AbstractFramebuffer&, AbstractFramebuffer&, const Range2Di&, const Range2Di&, FramebufferBlitMask, FramebufferBlitFilter);
GLenum(AbstractFramebuffer::*checkStatusImplementation)(FramebufferTarget);
void(AbstractFramebuffer::*drawBuffersImplementation)(GLsizei, const GLenum*);
void(AbstractFramebuffer::*drawBufferImplementation)(GLenum);

8
src/Magnum/Renderbuffer.cpp

@ -138,6 +138,10 @@ void Renderbuffer::storageImplementationDefault(RenderbufferFormat internalForma
}
#ifndef MAGNUM_TARGET_GLES
void Renderbuffer::storageImplementationDSA(const RenderbufferFormat internalFormat, const Vector2i& size) {
glNamedRenderbufferStorage(_id, GLenum(internalFormat), size.x(), size.y());
}
void Renderbuffer::storageImplementationDSAEXT(RenderbufferFormat internalFormat, const Vector2i& size) {
_created = true;
glNamedRenderbufferStorageEXT(_id, GLenum(internalFormat), size.x(), size.y());
@ -176,6 +180,10 @@ void Renderbuffer::storageMultisampleImplementationNV(const GLsizei samples, con
#endif
#ifndef MAGNUM_TARGET_GLES
void Renderbuffer::storageMultisampleImplementationDSA(const GLsizei samples, const RenderbufferFormat internalFormat, const Vector2i& size) {
glNamedRenderbufferStorageMultisample(_id, samples, GLenum(internalFormat), size.x(), size.y());
}
void Renderbuffer::storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size) {
_created = true;
glNamedRenderbufferStorageMultisampleEXT(_id, samples, GLenum(internalFormat), size.x(), size.y());

33
src/Magnum/Renderbuffer.h

@ -51,9 +51,11 @@ The engine tracks currently bound renderbuffer to avoid unnecessary calls to
implementation-defined values (such as @ref maxSize()) are cached, so repeated
queries don't result in repeated @fn_gl{Get} calls.
If extension @extension{EXT,direct_state_access} is available, function
@ref setStorage() uses DSA to avoid unnecessary calls to @fn_gl{BindRenderbuffer}.
See its documentation for more information.
If not on OpenGL ES and either @extension{ARB,direct_state_access} (part of
OpenGL 4.5) or @extension{EXT,direct_state_access} is available, functions
@ref setStorage() and @ref setStorageMultisample() use DSA to avoid unnecessary
calls to @fn_gl{BindRenderbuffer}. See their respective documentation for more
information.
@requires_gl30 Extension @extension{ARB,framebuffer_object}
*/
@ -153,11 +155,12 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
* @param internalFormat Internal format
* @param size Renderbuffer size
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @ref maxSize(), @fn_gl{BindRenderbuffer}, @fn_gl{RenderbufferStorage}
* or @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the renderbuffer is bound before the operation (if not already).
* @see @ref maxSize(), @fn_gl2{NamedRenderbufferStorage,RenderbufferStorage},
* @fn_gl_extension{NamedRenderbufferStorage,EXT,direct_state_access},
* eventually @fn_gl{BindRenderbuffer} and @fn_gl{RenderbufferStorage}
*/
void setStorage(RenderbufferFormat internalFormat, const Vector2i& size);
@ -167,11 +170,13 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
* @param internalFormat Internal format
* @param size Renderbuffer size
*
* If @extension{EXT,direct_state_access} is not available and the
* framebufferbuffer is not currently bound, it is bound before the
* operation.
* @see @ref maxSize(), @ref maxSamples(), @fn_gl{BindRenderbuffer},
* @fn_gl{RenderbufferStorageMultisample} or @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access}
* If on OpenGL ES or neither @extension{ARB,direct_state_access} (part
* of OpenGL 4.5) nor @extension{EXT,direct_state_access} is available,
* the renderbuffer is bound before the operation (if not already).
* @see @ref maxSize(), @ref maxSamples(),
* @fn_gl2{NamedRenderbufferStorageMultisample,RenderbufferStorageMultisample},
* @fn_gl_extension{NamedRenderbufferStorageMultisample,EXT,direct_state_access},
* eventually @fn_gl{BindRenderbuffer} and @fn_gl{RenderbufferStorageMultisample}
* @requires_gles30 Extension @es_extension{ANGLE,framebuffer_multisample}
* or @es_extension{NV,framebuffer_multisample} in OpenGL ES 2.0
* @todo How about @es_extension{APPLE,framebuffer_multisample}?
@ -191,12 +196,14 @@ class MAGNUM_EXPORT Renderbuffer: public AbstractObject {
void MAGNUM_LOCAL storageImplementationDefault(RenderbufferFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageImplementationDSA(RenderbufferFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageImplementationDSAEXT(RenderbufferFormat internalFormat, const Vector2i& size);
#endif
#ifndef MAGNUM_TARGET_GLES2
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
void MAGNUM_LOCAL storageMultisampleImplementationDSAEXT(GLsizei samples, RenderbufferFormat internalFormat, const Vector2i& size);
#endif
#else

Loading…
Cancel
Save