Browse Source

Added MultisampleTexture::setStorage().

With this function multisample texture implementation is pretty much
done. Also implemented all the tests.
pull/51/head
Vladimír Vondruš 12 years ago
parent
commit
0a2b8088a6
  1. 4
      doc/opengl-support.dox
  2. 40
      src/Magnum/AbstractTexture.cpp
  3. 14
      src/Magnum/AbstractTexture.h
  4. 19
      src/Magnum/Implementation/TextureState.cpp
  5. 2
      src/Magnum/Implementation/TextureState.h
  6. 1
      src/Magnum/Magnum.h
  7. 50
      src/Magnum/MultisampleTexture.h
  8. 48
      src/Magnum/Test/MultisampleTextureGLTest.cpp

4
doc/opengl-support.dox

@ -100,7 +100,7 @@ following:
@extension{ARB,provoking_vertex} | done
@extension{ARB,seamless_cube_map} | done
@extension{ARB,sync} | |
@extension{ARB,texture_multisample} | |
@extension{ARB,texture_multisample} | missing sample location queries and sample mask
@extension{ARB,vertex_array_bgra} | done
@subsection opengl-support-33 OpenGL 3.3
@ -187,7 +187,7 @@ following:
@extension{ARB,stencil_texturing} | |
@extension{ARB,texture_buffer_range} | done
@extension{ARB,texture_query_levels} | done (shading language only)
@extension{ARB,texture_storage_multisample} | |
@extension{ARB,texture_storage_multisample} | done
@extension{ARB,texture_view} | |
@extension{ARB,vertex_attrib_binding} | |

40
src/Magnum/AbstractTexture.cpp

@ -885,6 +885,36 @@ void AbstractTexture::storageImplementationDSA(GLenum target, GLsizei levels, Te
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexImage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexStorage2DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDSA(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
glTextureStorage2DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationFallback(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexImage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDefault(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
bindInternal();
glTexStorage3DMultisample(target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
void AbstractTexture::storageMultisampleImplementationDSA(const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
glTextureStorage3DMultisampleEXT(_id, target, samples, GLenum(internalFormat), size.x(), size.y(), size.z(), fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::getImageImplementationDefault(const GLenum target, const GLint level, const ColorFormat format, const ColorType type, const std::size_t, GLvoid* const data) {
bindInternal();
@ -1092,6 +1122,16 @@ void AbstractTexture::DataHelper<3>::setStorage(AbstractTexture& texture, const
(texture.*Context::current()->state().texture->storage3DImplementation)(target, levels, internalFormat, size);
}
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<2>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector2i& size, const GLboolean fixedSampleLocations) {
(texture.*Context::current()->state().texture->storage2DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations);
}
void AbstractTexture::DataHelper<3>::setStorageMultisample(AbstractTexture& texture, const GLenum target, const GLsizei samples, const TextureFormat internalFormat, const Vector3i& size, const GLboolean fixedSampleLocations) {
(texture.*Context::current()->state().texture->storage3DMultisampleImplementation)(target, samples, internalFormat, size, fixedSampleLocations);
}
#endif
#ifndef MAGNUM_TARGET_GLES
void AbstractTexture::DataHelper<1>::setImage(AbstractTexture& texture, const GLenum target, const GLint level, const TextureFormat internalFormat, const ImageReference1D& image) {
Buffer::unbind(Buffer::Target::PixelUnpack);

14
src/Magnum/AbstractTexture.h

@ -350,6 +350,16 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
void MAGNUM_LOCAL storageImplementationDSA(GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationFallback(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDefault(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
void MAGNUM_LOCAL storageMultisampleImplementationDSA(GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedsamplelocations);
#endif
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL getImageImplementationDefault(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
void MAGNUM_LOCAL getImageImplementationDSA(GLenum target, GLint level, ColorFormat format, ColorType type, std::size_t dataSize, GLvoid* data);
@ -446,6 +456,8 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<2> {
static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector2i& size);
static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector2i& size, GLboolean fixedSampleLocations);
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference2D& image);
#ifndef MAGNUM_TARGET_GLES2
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage2D& image);
@ -481,6 +493,8 @@ template<> struct MAGNUM_EXPORT AbstractTexture::DataHelper<3> {
static void setStorage(AbstractTexture& texture, GLenum target, GLsizei levels, TextureFormat internalFormat, const Vector3i& size);
static void setStorageMultisample(AbstractTexture& texture, GLenum target, GLsizei samples, TextureFormat internalFormat, const Vector3i& size, GLboolean fixedSampleLocations);
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, const ImageReference3D& image);
#ifndef MAGNUM_TARGET_GLES2
static void setImage(AbstractTexture& texture, GLenum target, GLint level, TextureFormat internalFormat, BufferImage3D& image);

19
src/Magnum/Implementation/TextureState.cpp

@ -179,6 +179,25 @@ TextureState::TextureState(Context& context, std::vector<std::string>& extension
}
#endif
#ifndef MAGNUM_TARGET_GLES
/* Storage implementation for multisample textures. The fallback doesn't
have DSA alternative, so it must be handled specially. */
if(context.isExtensionSupported<Extensions::GL::ARB::texture_storage_multisample>()) {
extensions.push_back(Extensions::GL::ARB::texture_storage_multisample::string());
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDSA;
} else {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationDefault;
}
} else {
storage2DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationFallback;
storage3DMultisampleImplementation = &AbstractTexture::storageMultisampleImplementationFallback;
}
#endif
/* Anisotropic filter implementation */
if(context.isExtensionSupported<Extensions::GL::EXT::texture_filter_anisotropic>()) {
extensions.push_back(Extensions::GL::EXT::texture_filter_anisotropic::string());

2
src/Magnum/Implementation/TextureState.h

@ -54,6 +54,8 @@ struct TextureState {
void(AbstractTexture::*storage2DImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&);
void(AbstractTexture::*storage3DImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&);
#ifndef MAGNUM_TARGET_GLES
void(AbstractTexture::*storage2DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector2i&, GLboolean);
void(AbstractTexture::*storage3DMultisampleImplementation)(GLenum, GLsizei, TextureFormat, const Vector3i&, GLboolean);
void(AbstractTexture::*getImageImplementation)(GLenum, GLint, ColorFormat, ColorType, std::size_t, GLvoid*);
void(AbstractTexture::*image1DImplementation)(GLenum, GLint, TextureFormat, const Math::Vector<1, GLsizei>&, ColorFormat, ColorType, const GLvoid*);
#endif

1
src/Magnum/Magnum.h

@ -594,6 +594,7 @@ class Mesh;
class MeshView;
#ifndef MAGNUM_TARGET_GLES
/* MultisampleTextureSampleLocations enum used only in the function */
template<UnsignedInt> class MultisampleTexture;
typedef MultisampleTexture<2> MultisampleTexture2D;
typedef MultisampleTexture<3> MultisampleTexture2DArray;

50
src/Magnum/MultisampleTexture.h

@ -44,6 +44,16 @@ namespace Implementation {
template<> inline constexpr GLenum multisampleTextureTarget<3>() { return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; }
}
/**
@brief Multisample texture sample locations
@see @ref MultisampleTexture::setStorage()
*/
enum class MultisampleTextureSampleLocations: GLboolean {
NotFixed = GL_FALSE,
Fixed = GL_TRUE
};
/**
@brief Mulitsample texture
@ -92,6 +102,46 @@ template<UnsignedInt dimensions> class MultisampleTexture: public AbstractTextur
return DataHelper<dimensions>::imageSize(*this, _target, 0);
}
/**
* @brief Set storage
* @param samples Sample count
* @param internalFormat Internal format
* @param size %Texture size
* @param sampleLocations Whether to use fixed sample locations
* @return Reference to self (for method chaining)
*
* After calling this function the texture is immutable and calling
* @ref setStorage() again is not allowed.
*
* If @extension{EXT,direct_state_access} is not available, the texture
* is bound to some texture unit before the operation. If
* @extension{ARB,texture_storage_multisample} (part of OpenGL 4.3) is
* not available, the feature is emulated using plain
* @extension{ARB,texture_storage} functionality (which unfortunately
* doesn't have any DSA alternative, so the texture must be bound
* to some texture unit before).
* @see @ref maxColorSamples(), @ref maxDepthSamples(),
* @ref maxIntegerSamples(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture}
* and @fn_gl{TexStorage2DMultisample}/@fn_gl{TexStorage3DMultisample}
* or @fn_gl_extension{TextureStorage2DMultisample,EXT,direct_state_access}/
* @fn_gl_extension{TextureStorage3DMultisample,EXT,direct_state_access}
* eventually @fn_gl{TexImage2DMultisample}/@fn_gl{TexImage3DMultisample}
* @todoc Remove the workaround when it stops breaking Doxygen layout so badly
*/
/* The default parameter value was chosen based on discussion in
ARB_texture_multisample specs (fixed locations is treated as the
special case) */
MultisampleTexture<dimensions>& setStorage(Int samples, TextureFormat internalFormat, const typename DimensionTraits<dimensions, Int>::VectorType& size, MultisampleTextureSampleLocations sampleLocations =
#ifndef DOXYGEN_GENERATING_OUTPUT
MultisampleTextureSampleLocations::NotFixed
#else
NotFixed
#endif
) {
DataHelper<dimensions>::setStorageMultisample(*this, _target, samples, internalFormat, size, GLboolean(sampleLocations));
return *this;
}
/** @copydoc RectangleTexture::invalidateImage() */
void invalidateImage() { AbstractTexture::invalidateImage(0); }

48
src/Magnum/Test/MultisampleTextureGLTest.cpp

@ -26,6 +26,8 @@
#include <Corrade/TestSuite/Compare/Container.h>
#include "Magnum/MultisampleTexture.h"
#include "Magnum/TextureFormat.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/Test/AbstractOpenGLTester.h"
namespace Magnum { namespace Test {
@ -103,8 +105,8 @@ void MultisampleTextureGLTest::bind2D() {
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setStorage(4, TextureFormat::RGBA8, {16, 16});
CORRADE_VERIFY(false);
CORRADE_SKIP("...but we don't have any function to do that yet.");
}
texture.bind(15);
@ -128,8 +130,8 @@ void MultisampleTextureGLTest::bind2DArray() {
if(Context::current()->isExtensionSupported<Extensions::GL::ARB::multi_bind>()) {
CORRADE_EXPECT_FAIL("With ARB_multi_bind the texture must be associated with given target at least once before binding it.");
texture.setStorage(4, TextureFormat::RGBA8, {16, 16, 5});
CORRADE_VERIFY(false);
CORRADE_SKIP("...but we don't have any function to do that yet.");
}
texture.bind(15);
@ -149,42 +151,72 @@ void MultisampleTextureGLTest::storage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
MultisampleTexture2D texture;
texture.setStorage(4, TextureFormat::RGBA8, {16, 16});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(), Vector2i(16, 16));
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::storage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Not implemented yet.");
MultisampleTexture2DArray texture;
texture.setStorage(4, TextureFormat::RGBA8, {16, 16, 5});
MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(texture.imageSize(), Vector3i(16, 16, 5));
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::invalidateImage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
MultisampleTexture2D texture;
texture.setStorage(4, TextureFormat::RGBA8, {16, 16});
texture.invalidateImage();
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::invalidateImage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
MultisampleTexture2DArray texture;
texture.setStorage(4, TextureFormat::RGBA8, {16, 16, 5});
texture.invalidateImage();
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::invalidateSubImage2D() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
MultisampleTexture2D texture;
texture.setStorage(4, TextureFormat::RGBA8, {16, 16});
texture.invalidateSubImage({3, 4}, {5, 6});
MAGNUM_VERIFY_NO_ERROR();
}
void MultisampleTextureGLTest::invalidateSubImage2DArray() {
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::texture_multisample>())
CORRADE_SKIP(Extensions::GL::ARB::texture_multisample::string() + std::string(" is not supported."));
CORRADE_SKIP("Multisample storage is not implemented yet.");
MultisampleTexture2DArray texture;
texture.setStorage(4, TextureFormat::RGBA8, {16, 16, 5});
texture.invalidateSubImage({3, 4, 1}, {5, 6, 3});
MAGNUM_VERIFY_NO_ERROR();
}
}}

Loading…
Cancel
Save