Browse Source

VectorGL & tests

pull/576/head
Vladislav Oleshko 4 years ago
parent
commit
fefb99d24d
  1. 94
      src/Magnum/Shaders/Test/VectorGLTest.cpp
  2. 63
      src/Magnum/Shaders/VectorGL.cpp
  3. 38
      src/Magnum/Shaders/VectorGL.h

94
src/Magnum/Shaders/Test/VectorGLTest.cpp

@ -31,6 +31,7 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/Path.h>
#ifdef CORRADE_TARGET_APPLE
@ -83,8 +84,10 @@ struct VectorGLTest: GL::OpenGLTester {
explicit VectorGLTest();
template<UnsignedInt dimensions> void construct();
template<UnsignedInt dimensions> void constructAsync();
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> void constructUniformBuffers();
template<UnsignedInt dimensions> void constructUniformBuffersAsync();
#endif
template<UnsignedInt dimensions> void constructMove();
@ -247,11 +250,19 @@ VectorGLTest::VectorGLTest() {
&VectorGLTest::construct<3>},
Containers::arraySize(ConstructData));
addTests<VectorGLTest>({
&VectorGLTest::constructAsync<2>,
&VectorGLTest::constructAsync<3>});
#ifndef MAGNUM_TARGET_GLES2
addInstancedTests<VectorGLTest>({
&VectorGLTest::constructUniformBuffers<2>,
&VectorGLTest::constructUniformBuffers<3>},
Containers::arraySize(ConstructUniformBuffersData));
addTests<VectorGLTest>({
&VectorGLTest::constructUniformBuffersAsync<2>,
&VectorGLTest::constructUniformBuffersAsync<3>});
#endif
addTests<VectorGLTest>({
@ -370,6 +381,38 @@ template<UnsignedInt dimensions> void VectorGLTest::construct() {
MAGNUM_VERIFY_NO_GL_ERROR();
}
template<UnsignedInt dimensions> void VectorGLTest::constructAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
constexpr struct {
const char* name;
VectorGL2D::Flags flags;
} data {
"texture transformation", VectorGL2D::Flag::TextureTransformation
};
setTestCaseDescription(data.name);
auto compileState = VectorGL<dimensions>::compile(data.flags);
CORRADE_COMPARE(compileState.flags(), data.flags);
while(!compileState.isLinkFinished())
Utility::System::sleep(100);
VectorGL<dimensions> shader{std::move(compileState)};
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_COMPARE(shader.flags(), data.flags);
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
#endif
CORRADE_VERIFY(shader.validate().first);
}
MAGNUM_VERIFY_NO_GL_ERROR();
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> void VectorGLTest::constructUniformBuffers() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
@ -408,6 +451,57 @@ template<UnsignedInt dimensions> void VectorGLTest::constructUniformBuffers() {
MAGNUM_VERIFY_NO_GL_ERROR();
}
template<UnsignedInt dimensions> void VectorGLTest::constructUniformBuffersAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
constexpr struct {
const char* name;
VectorGL2D::Flags flags;
UnsignedInt materialCount, drawCount;
} data {"texture transformation", VectorGL2D::Flag::UniformBuffers|VectorGL2D::Flag::TextureTransformation, 1, 1};
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
if((data.flags & VectorGL<dimensions>::Flag::UniformBuffers) && !GL::Context::current().isExtensionSupported<GL::Extensions::ARB::uniform_buffer_object>())
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
if(data.flags >= VectorGL2D::Flag::MultiDraw) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::shader_draw_parameters>())
CORRADE_SKIP(GL::Extensions::ARB::shader_draw_parameters::string() << "is not supported.");
#elif !defined(MAGNUM_TARGET_WEBGL)
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ANGLE::multi_draw>())
CORRADE_SKIP(GL::Extensions::ANGLE::multi_draw::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::WEBGL::multi_draw>())
CORRADE_SKIP(GL::Extensions::WEBGL::multi_draw::string() << "is not supported.");
#endif
}
auto compileState = VectorGL<dimensions>::compile(data.flags, data.materialCount, data.drawCount);
CORRADE_COMPARE(compileState.flags(), data.flags);
CORRADE_COMPARE(compileState.materialCount(), data.materialCount);
CORRADE_COMPARE(compileState.drawCount(), data.drawCount);
while(!compileState.isLinkFinished())
Utility::System::sleep(100);
VectorGL<dimensions> shader{std::move(compileState)};
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_COMPARE(shader.flags(), data.flags);
CORRADE_COMPARE(shader.drawCount(), data.drawCount);
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
#endif
CORRADE_VERIFY(shader.validate().first);
}
MAGNUM_VERIFY_NO_GL_ERROR();
}
#endif
template<UnsignedInt dimensions> void VectorGLTest::constructMove() {

63
src/Magnum/Shaders/VectorGL.cpp

@ -63,21 +63,16 @@ namespace {
#endif
}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flags
template<UnsignedInt dimensions> typename VectorGL<dimensions>::CompileState VectorGL<dimensions>::compile(const Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
):
_flags{flags}
#ifndef MAGNUM_TARGET_GLES2
, _materialCount{materialCount}, _drawCount{drawCount}
#endif
{
) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || materialCount,
"Shaders::VectorGL: material count can't be zero", );
"Shaders::VectorGL: material count can't be zero", CompileState{NoCreate});
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || drawCount,
"Shaders::VectorGL: draw count can't be zero", );
"Shaders::VectorGL: draw count can't be zero", CompileState{NoCreate});
#endif
#ifndef MAGNUM_TARGET_GLES
@ -141,9 +136,17 @@ template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flag
frag.addSource(rs.getString("generic.glsl"))
.addSource(rs.getString("Vector.frag"));
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag}));
vert.submitCompile();
frag.submitCompile();
VectorGL out{NoInit};
out._flags = flags;
#ifndef MAGNUM_TARGET_GLES2
out._materialCount = materialCount;
out._drawCount = drawCount;
#endif
attachShaders({vert, frag});
out.attachShaders({vert, frag});
/* ES3 has this done in the shader directly */
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
@ -151,25 +154,41 @@ template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flag
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version))
#endif
{
bindAttributeLocation(Position::Location, "position");
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
out.bindAttributeLocation(Position::Location, "position");
out.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
}
#endif
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
out.submitLink();
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(CompileState&& cs)
: VectorGL{static_cast<VectorGL&&>(std::move(cs))} {
if (id() == 0) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
CORRADE_INTERNAL_ASSERT_OUTPUT(cs._vert.checkCompile());
CORRADE_INTERNAL_ASSERT_OUTPUT(cs._frag.checkCompile());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
#endif
{
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
if(_flags >= Flag::UniformBuffers) {
if(_drawCount > 1) _drawOffsetUniform = uniformLocation("drawOffset");
} else
#endif
{
_transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
if(flags & Flag::TextureTransformation)
if(_flags & Flag::TextureTransformation)
_textureMatrixUniform = uniformLocation("textureMatrix");
_backgroundColorUniform = uniformLocation("backgroundColor");
_colorUniform = uniformLocation("color");
@ -182,10 +201,10 @@ template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flag
{
setUniform(uniformLocation("vectorTexture"), TextureUnit);
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
if(_flags >= Flag::UniformBuffers) {
setUniformBlockBinding(uniformBlockIndex("TransformationProjection"), TransformationProjectionBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Draw"), DrawBufferBinding);
if(flags & Flag::TextureTransformation)
if(_flags & Flag::TextureTransformation)
setUniformBlockBinding(uniformBlockIndex("TextureTransformation"), TextureTransformationBufferBinding);
setUniformBlockBinding(uniformBlockIndex("Material"), MaterialBufferBinding);
}
@ -195,13 +214,13 @@ template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flag
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::UniformBuffers) {
if(_flags >= Flag::UniformBuffers) {
/* Draw offset is zero by default */
} else
#endif
{
setTransformationProjectionMatrix(MatrixTypeFor<dimensions, Float>{Math::IdentityInit});
if(flags & Flag::TextureTransformation)
if(_flags & Flag::TextureTransformation)
setTextureMatrix(Matrix3{Math::IdentityInit});
/* Background color is zero by default */
setColor(Color4{1.0f});
@ -209,10 +228,6 @@ template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flag
#endif
}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flags): VectorGL{flags, 1, 1} {}
#endif
template<UnsignedInt dimensions> VectorGL<dimensions>& VectorGL<dimensions>::setTransformationProjectionMatrix(const MatrixTypeFor<dimensions, Float>& matrix) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(_flags >= Flag::UniformBuffers),

38
src/Magnum/Shaders/VectorGL.h

@ -32,6 +32,7 @@
#include "Magnum/DimensionTraits.h"
#include "Magnum/GL/AbstractShaderProgram.h"
#include "Magnum/GL/Shader.h"
#include "Magnum/Shaders/GenericGL.h"
#include "Magnum/Shaders/visibility.h"
@ -221,7 +222,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
* @ref VectorGL(Flags, UnsignedInt, UnsignedInt) with @p materialCount
* and @p drawCount set to @cpp 1 @ce.
*/
explicit VectorGL(Flags flags = {});
explicit VectorGL(Flags flags = {}) : VectorGL{compile(flags)} {};
#ifndef MAGNUM_TARGET_GLES2
/**
@ -256,7 +257,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
for this might be too confusing); what if some parameters won't be
(unsigned) integers? like a string with shader extensions? make a
whole Configuration class? */
explicit VectorGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
explicit VectorGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount) :
VectorGL{compile(flags, materialCount, drawCount)} {}
#endif
/**
@ -273,6 +275,22 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
*/
explicit VectorGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
class CompileState;
explicit VectorGL(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags) {
return compile(flags, 1, 1);
}
#endif
/** @brief Copying is not allowed */
VectorGL(const VectorGL<dimensions>&) = delete;
@ -554,6 +572,9 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
#endif
private:
/* Creates the GL shader program object but nothing else. Internal, used by compile(). */
explicit VectorGL(NoInitT) {}
/* Prevent accidentally calling irrelevant functions */
#ifndef MAGNUM_TARGET_GLES
using GL::AbstractShaderProgram::drawTransformFeedback;
@ -577,6 +598,19 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
#endif
};
template<UnsignedInt dimensions> class VectorGL<dimensions>::CompileState : public VectorGL<dimensions> {
private:
friend class VectorGL;
explicit CompileState(NoCreateT) : VectorGL{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(VectorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version) :
VectorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag;
GL::Version _version;
};
/**
@brief Two-dimensional vector OpenGL shader
@m_since_latest

Loading…
Cancel
Save