Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async GL shader compilation #576

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
51c8ba7
Basic async shader compilation for FlatGL
dranikpg Jul 8, 2022
1ae63af
Merge branch 'master' into async-shader-compile
dranikpg Jul 18, 2022
37b47f1
Refactor FlatGL::CompileState
dranikpg Jul 25, 2022
66015a2
Move shader compilation/linking to member functions
dranikpg Jul 25, 2022
8bcd04a
Refactor FlatGL::CompileState
dranikpg Jul 27, 2022
89582ef
Update doc comments
dranikpg Jul 27, 2022
05d49d6
Implement completion status fallback & fixes
dranikpg Jul 27, 2022
fa26cfc
More small fixes
dranikpg Jul 28, 2022
0acc265
Fix wrong access
dranikpg Jul 29, 2022
6fe87cc
Implement tests for compile/link/flat
dranikpg Aug 1, 2022
1a1c045
Fixes: docs, tests
dranikpg Aug 6, 2022
fefb99d
VectorGL & tests
dranikpg Aug 9, 2022
e1ec1a6
MeshVisualizerGL3D & tests
dranikpg Aug 11, 2022
3c899c1
Small fixes
dranikpg Aug 13, 2022
cf9b90f
PhongGL & tests
dranikpg Aug 13, 2022
09ab0ef
Fixes
dranikpg Aug 13, 2022
fdb1dca
VertexColor & tests
dranikpg Aug 15, 2022
e3e05cd
Small fix in PhongGL construct
dranikpg Aug 15, 2022
511d869
DistanceFieldVector & tests. Fix deprecated references
dranikpg Aug 21, 2022
1d6c99d
Move FlatGL impls from header
dranikpg Aug 23, 2022
b086162
Move VectorGL impls from header
dranikpg Aug 23, 2022
b5da1e2
Move VertexColorGL impls from header
dranikpg Aug 23, 2022
3ab4b6f
Refactor tests
dranikpg Aug 23, 2022
b592fcb
Fix formatting
dranikpg Aug 24, 2022
dd51e27
Fix MeshVisualizer & tests
dranikpg Aug 24, 2022
9a0af4d
Fix unused vars
dranikpg Aug 24, 2022
1e363fd
Fix MeshVisualizer test case
dranikpg Aug 24, 2022
ebbed67
Fixes
dranikpg Sep 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions src/Magnum/GL/Test/AbstractShaderProgramGLTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <Corrade/Containers/Reference.h>
#include <Corrade/Containers/StringStl.h> /** @todo remove when Shader is <string>-free */
#include <Corrade/TestSuite/Compare/Container.h>
#include <Corrade/TestSuite/Compare/String.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Resource.h>

Expand Down Expand Up @@ -68,8 +69,11 @@ struct AbstractShaderProgramGLTest: OpenGLTester {
#ifndef MAGNUM_TARGET_GLES
void createMultipleOutputsIndexed();
#endif
void createAsync();

void linkFailure();
void linkFailureAsync();

void uniformNotFound();

void uniform();
Expand Down Expand Up @@ -103,12 +107,14 @@ AbstractShaderProgramGLTest::AbstractShaderProgramGLTest() {
#endif

&AbstractShaderProgramGLTest::create,
&AbstractShaderProgramGLTest::createAsync,
&AbstractShaderProgramGLTest::createMultipleOutputs,
#ifndef MAGNUM_TARGET_GLES
&AbstractShaderProgramGLTest::createMultipleOutputsIndexed,
#endif

&AbstractShaderProgramGLTest::linkFailure,
&AbstractShaderProgramGLTest::linkFailureAsync,
&AbstractShaderProgramGLTest::uniformNotFound,

&AbstractShaderProgramGLTest::uniform,
Expand Down Expand Up @@ -205,6 +211,8 @@ struct MyPublicShader: AbstractShaderProgram {
using AbstractShaderProgram::bindFragmentDataLocation;
#endif
using AbstractShaderProgram::link;
using AbstractShaderProgram::submitLink;
using AbstractShaderProgram::checkLink;
using AbstractShaderProgram::uniformLocation;
#ifndef MAGNUM_TARGET_GLES2
using AbstractShaderProgram::uniformBlockIndex;
Expand Down Expand Up @@ -257,6 +265,74 @@ void AbstractShaderProgramGLTest::create() {

MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_VERIFY(linked);
// TODO: decide on this.
//CORRADE_VERIFY(program.isLinkFinished());
dranikpg marked this conversation as resolved.
Show resolved Hide resolved
{
#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(valid);
}

const Int matrixUniform = program.uniformLocation("matrix");
const Int multiplierUniform = program.uniformLocation("multiplier");
const Int colorUniform = program.uniformLocation("color");
const Int additionsUniform = program.uniformLocation("additions");

MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_VERIFY(matrixUniform >= 0);
CORRADE_VERIFY(multiplierUniform >= 0);
CORRADE_VERIFY(colorUniform >= 0);
CORRADE_VERIFY(additionsUniform >= 0);
}

void AbstractShaderProgramGLTest::createAsync() {
Utility::Resource rs("AbstractShaderProgramGLTest");

Shader vert(
#ifndef MAGNUM_TARGET_GLES
#ifndef CORRADE_TARGET_APPLE
Version::GL210
#else
Version::GL310
#endif
#else
Version::GLES200
#endif
, Shader::Type::Vertex);
vert.addSource(rs.getString("MyShader.vert"));
const bool vertCompiled = vert.compile();

Shader frag(
#ifndef MAGNUM_TARGET_GLES
#ifndef CORRADE_TARGET_APPLE
Version::GL210
#else
Version::GL310
#endif
#else
Version::GLES200
#endif
, Shader::Type::Fragment);
frag.addSource(rs.getString("MyShader.frag"));
const bool fragCompiled = frag.compile();

MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_VERIFY(vertCompiled);
CORRADE_VERIFY(fragCompiled);

MyPublicShader program;
program.attachShaders({vert, frag});

MAGNUM_VERIFY_NO_GL_ERROR();

program.bindAttributeLocation(0, "position");
program.submitLink();

CORRADE_VERIFY(program.checkLink());
const bool valid = program.validate().first;

MAGNUM_VERIFY_NO_GL_ERROR();
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
Expand Down Expand Up @@ -412,6 +488,39 @@ void AbstractShaderProgramGLTest::linkFailure() {
CORRADE_VERIFY(!program.link());
}

void AbstractShaderProgramGLTest::linkFailureAsync() {
Shader shader(
#ifndef MAGNUM_TARGET_GLES
#ifndef CORRADE_TARGET_APPLE
Version::GL210
#else
Version::GL310
#endif
#else
Version::GLES200
#endif
, Shader::Type::Fragment);
shader.addSource("[fu] bleh error #:! stuff\n");

{
Error redirectError{nullptr};
CORRADE_VERIFY(!shader.compile());
}

MyPublicShader program;
program.attachShaders({shader});

std::ostringstream out;
Error redirectError{&out};

program.submitLink();
CORRADE_VERIFY(out.str().empty());

CORRADE_VERIFY(!program.checkLink());
CORRADE_COMPARE_AS(out.str(), "GL::AbstractShaderProgram::link(): linking failed with the following message:",
TestSuite::Compare::StringHasPrefix);
}

void AbstractShaderProgramGLTest::uniformNotFound() {
MyPublicShader program;

Expand Down
68 changes: 52 additions & 16 deletions src/Magnum/GL/Test/ShaderGLTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
DEALINGS IN THE SOFTWARE.
*/

#include <sstream>
#include <Corrade/Containers/StringStl.h> /** @todo remove once Shader is <string>-free */
#include <Corrade/TestSuite/Compare/String.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Path.h>

Expand All @@ -40,6 +42,18 @@

namespace Magnum { namespace GL { namespace Test { namespace {

constexpr GL::Version shaderCompileGLVersion =
#ifndef MAGNUM_TARGET_GLES
#ifndef CORRADE_TARGET_APPLE
Version::GL210
#else
Version::GL310
#endif
;
#else
Version::GLES200;
#endif
dranikpg marked this conversation as resolved.
Show resolved Hide resolved

struct ShaderGLTest: OpenGLTester {
explicit ShaderGLTest();

Expand All @@ -55,6 +69,9 @@ struct ShaderGLTest: OpenGLTester {
void addSourceNoVersion();
void addFile();
void compile();
void compileFailure();
void compileAsync();
void compileAsyncFailure();
void compileUtf8();
void compileNoVersion();
};
Expand All @@ -72,6 +89,9 @@ ShaderGLTest::ShaderGLTest() {
&ShaderGLTest::addSourceNoVersion,
&ShaderGLTest::addFile,
&ShaderGLTest::compile,
&ShaderGLTest::compileFailure,
&ShaderGLTest::compileAsync,
&ShaderGLTest::compileAsyncFailure,
&ShaderGLTest::compileUtf8,
&ShaderGLTest::compileNoVersion});
}
Expand Down Expand Up @@ -262,25 +282,41 @@ void ShaderGLTest::addFile() {
}

void ShaderGLTest::compile() {
#ifndef MAGNUM_TARGET_GLES
constexpr Version v =
#ifndef CORRADE_TARGET_APPLE
Version::GL210
#else
Version::GL310
#endif
;
#else
constexpr Version v = Version::GLES200;
#endif

Shader shader(v, Shader::Type::Fragment);
Shader shader(shaderCompileGLVersion, Shader::Type::Fragment);
shader.addSource("void main() {}\n");

CORRADE_VERIFY(shader.compile());
CORRADE_VERIFY(shader.isCompileFinished());
}

void ShaderGLTest::compileFailure() {
Shader shader(shaderCompileGLVersion, Shader::Type::Fragment);
shader.addSource("[fu] bleh error #:! stuff\n");

CORRADE_VERIFY(!shader.compile());
CORRADE_VERIFY(shader.isCompileFinished());
}

void ShaderGLTest::compileAsync() {
Shader shader(shaderCompileGLVersion, Shader::Type::Fragment);
shader.addSource("void main() {}\n");
shader.submitCompile();

CORRADE_VERIFY(shader.checkCompile());
}

void ShaderGLTest::compileAsyncFailure() {
Shader shader(shaderCompileGLVersion, Shader::Type::Fragment);
shader.addSource("[fu] bleh error #:! stuff\n");
shader.submitCompile();

std::ostringstream out;
Error redirectError{&out};
CORRADE_VERIFY(out.str().empty());

Shader shader2(v, Shader::Type::Fragment);
shader2.addSource("[fu] bleh error #:! stuff\n");
CORRADE_VERIFY(!shader2.compile());
CORRADE_VERIFY(!shader.checkCompile());
CORRADE_COMPARE_AS(out.str(), "GL::Shader::compile(): compilation of fragment shader failed with the following message:",
TestSuite::Compare::StringHasPrefix);
}

void ShaderGLTest::compileUtf8() {
Expand Down
2 changes: 1 addition & 1 deletion src/Magnum/Shaders/FlatGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(CompileState&& cs)
: FlatGL{static_cast<FlatGL&&>(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());
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());

const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
Expand Down
Loading