diff --git a/CMakeLists.txt b/CMakeLists.txt index 36cf5ac91..3c5ac343e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,7 @@ endif() option(BUILD_STATIC "Build static libraries (default are shared)" OFF) cmake_dependent_option(BUILD_STATIC_PIC "Build static libraries with position-independent code" OFF "BUILD_STATIC" OFF) option(BUILD_TESTS "Build unit tests." OFF) +cmake_dependent_option(BUILD_GL_TESTS "Build unit tests for OpenGL code." OFF "BUILD_TESTS" OFF) if(BUILD_TESTS) enable_testing() endif() @@ -107,6 +108,16 @@ if(TARGET_DESKTOP_GLES) set(MAGNUM_TARGET_DESKTOP_GLES 1) endif() +if(BUILD_GL_TESTS) + if(UNIX AND (NOT MAGNUM_TARGET_GLES OR MAGNUM_TARGET_DESKTOP_GLES)) + set(WITH_WINDOWLESSGLXAPPLICATION ON) + find_package(X11 REQUIRED) + set(GL_TEST_LIBRARIES Magnum MagnumWindowlessGlxApplication ${X11_LIBRARIES}) + else() + message(FATAL_ERROR "Cannot run tests for OpenGL code on this platform. Set BUILD_GL_TESTS to OFF to skip building them.") + endif() +endif() + if(NOT BUILD_STATIC) set(SHARED_OR_STATIC SHARED) else() diff --git a/src/Test/AbstractOpenGLTester.h b/src/Test/AbstractOpenGLTester.h new file mode 100644 index 000000000..fe23735a2 --- /dev/null +++ b/src/Test/AbstractOpenGLTester.h @@ -0,0 +1,56 @@ +#ifndef Magnum_Test_AbstractOpenGLTester_h +#define Magnum_Test_AbstractOpenGLTester_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Renderer.h" + +#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_DESKTOP_GLES) +#include "Platform/WindowlessGlxApplication.h" +#else +#error Cannot run OpenGL tests on this platform +#endif + +namespace Magnum { namespace Test { + +class AbstractOpenGLTester: public TestSuite::Tester, public Platform::WindowlessApplication { + public: + explicit AbstractOpenGLTester(): Platform::WindowlessApplication({zero, nullptr}) {} + + using TestSuite::Tester::exec; + int exec() override { return TestSuite::Tester::exec(); } + + private: + static int zero; +}; + +int AbstractOpenGLTester::zero = 0; + +#define MAGNUM_VERIFY_NO_ERROR() CORRADE_COMPARE(Renderer::error(), Renderer::Error::NoError) + +}} + +#endif diff --git a/src/Test/BufferGLTest.cpp b/src/Test/BufferGLTest.cpp new file mode 100644 index 000000000..8e40094d1 --- /dev/null +++ b/src/Test/BufferGLTest.cpp @@ -0,0 +1,265 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Buffer.h" +#include "Context.h" +#include "Extensions.h" +#include "Test/AbstractOpenGLTester.h" + +namespace Magnum { namespace Test { + +class BufferGLTest: public AbstractOpenGLTester { + public: + explicit BufferGLTest(); + + void construct(); + void data(); + void map(); + void mapRange(); + void mapRangeExplicitFlush(); + #ifndef MAGNUM_TARGET_GLES2 + void copy(); + #endif + #ifndef MAGNUM_TARGET_GLES2 + void invalidate(); + #endif +}; + +BufferGLTest::BufferGLTest() { + addTests({&BufferGLTest::construct, + &BufferGLTest::data, + &BufferGLTest::map, + &BufferGLTest::mapRange, + &BufferGLTest::mapRangeExplicitFlush, + #ifndef MAGNUM_TARGET_GLES2 + &BufferGLTest::copy, + #endif + #ifndef MAGNUM_TARGET_GLES + &BufferGLTest::invalidate + #endif + }); +} + +void BufferGLTest::construct() { + Buffer buffer; + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(buffer.targetHint(), Buffer::Target::Array); + + CORRADE_COMPARE(buffer.size(), 0); + MAGNUM_VERIFY_NO_ERROR(); +} + +void BufferGLTest::data() { + Buffer buffer; + + constexpr char data[] = {2, 7, 5, 13, 25}; + buffer.setData(5, data, Buffer::Usage::StaticDraw); + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(buffer.size(), 5); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + const Containers::Array contents = buffer.data(); + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_COMPARE(contents.size(), 5); + CORRADE_COMPARE(contents[0], 2); + CORRADE_COMPARE(contents[1], 7); + CORRADE_COMPARE(contents[2], 5); + CORRADE_COMPARE(contents[3], 13); + CORRADE_COMPARE(contents[4], 25); + #endif + + constexpr char subData[] = {125, 3, 15}; + buffer.setSubData(1, 3, subData); + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_COMPARE(buffer.size(), 5); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + const Containers::Array subContents = buffer.subData(1, 3); + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_COMPARE(subContents.size(), 3); + CORRADE_COMPARE(subContents[0], 125); + CORRADE_COMPARE(subContents[1], 3); + CORRADE_COMPARE(subContents[2], 15); + #endif +} + +#ifndef MAGNUM_TARGET_GLES3 +void BufferGLTest::map() { + #ifdef MAGNUM_TARGET_GLES2 + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::OES::mapbuffer::string() + std::string(" is not supported")); + #endif + Buffer buffer; + + constexpr char data[] = {2, 7, 5, 13, 25}; + buffer.setData(data, Buffer::Usage::StaticDraw); + + #ifndef MAGNUM_TARGET_GLES2 + char* contents = reinterpret_cast(buffer.map(Buffer::MapAccess::ReadWrite)); + #else + char* contents = reinterpret_cast(buffer.map(Buffer::MapAccess::WriteOnly)); + #endif + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_VERIFY(contents); + #ifndef MAGNUM_TARGET_GLES2 + CORRADE_COMPARE(contents[2], 5); + #endif + contents[3] = 107; + + CORRADE_VERIFY(buffer.unmap()); + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + Containers::Array changedContents = buffer.data(); + CORRADE_COMPARE(changedContents.size(), 5); + CORRADE_COMPARE(changedContents[3], 107); + #endif +} +#endif + +void BufferGLTest::mapRange() { + #ifndef MAGNUM_TARGET_GLES2 + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::map_buffer_range::string() + std::string(" is not supported")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::map_buffer_range::string() + std::string(" is not supported")); + #endif + + constexpr char data[] = {2, 7, 5, 13, 25}; + Buffer buffer; + buffer.setData(data, Buffer::Usage::StaticDraw); + + char* contents = reinterpret_cast(buffer.map(1, 4, Buffer::MapFlag::Read|Buffer::MapFlag::Write)); + MAGNUM_VERIFY_NO_ERROR(); + + CORRADE_VERIFY(contents); + CORRADE_COMPARE(contents[2], 13); + contents[3] = 107; + + CORRADE_VERIFY(buffer.unmap()); + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + Containers::Array changedContents = buffer.data(); + CORRADE_COMPARE(changedContents.size(), 5); + CORRADE_COMPARE(changedContents[4], 107); + #endif +} + +void BufferGLTest::mapRangeExplicitFlush() { + #ifndef MAGNUM_TARGET_GLES2 + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::map_buffer_range::string() + std::string(" is not supported")); + #else + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::EXT::map_buffer_range::string() + std::string(" is not supported")); + #endif + + constexpr char data[] = {2, 7, 5, 13, 25}; + Buffer buffer; + buffer.setData(data, Buffer::Usage::StaticDraw); + + /* Map, set byte, don't flush and unmap */ + char* contents = reinterpret_cast(buffer.map(1, 4, Buffer::MapFlag::Write|Buffer::MapFlag::FlushExplicit)); + CORRADE_VERIFY(contents); + contents[2] = 99; + CORRADE_VERIFY(buffer.unmap()); + MAGNUM_VERIFY_NO_ERROR(); + + /* Unflushed range _might_ not be changed, thus nothing to test */ + + /* Map, set byte, flush and unmap */ + contents = reinterpret_cast(buffer.map(1, 4, Buffer::MapFlag::Write|Buffer::MapFlag::FlushExplicit)); + CORRADE_VERIFY(contents); + contents[3] = 107; + buffer.flushMappedRange(3, 1); + MAGNUM_VERIFY_NO_ERROR(); + CORRADE_VERIFY(buffer.unmap()); + MAGNUM_VERIFY_NO_ERROR(); + + /* Flushed range should be changed */ + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + Containers::Array changedContents = buffer.data(); + CORRADE_COMPARE(changedContents.size(), 5); + CORRADE_COMPARE(changedContents[4], 107); + #endif +} + +#ifndef MAGNUM_TARGET_GLES2 +void BufferGLTest::copy() { + Buffer buffer1; + constexpr char data[] = {2, 7, 5, 13, 25}; + buffer1.setData(data, Buffer::Usage::StaticDraw); + + Buffer buffer2; + buffer2.setData(5, nullptr, Buffer::Usage::StaticDraw); + + Buffer::copy(&buffer1, &buffer2, 1, 2, 3); + MAGNUM_VERIFY_NO_ERROR(); + + /** @todo How to verify the contents in ES? */ + #ifndef MAGNUM_TARGET_GLES + const Containers::Array subContents = buffer2.subData(2, 3); + CORRADE_COMPARE(subContents.size(), 3); + CORRADE_COMPARE(subContents[0], 7); + CORRADE_COMPARE(subContents[1], 5); + CORRADE_COMPARE(subContents[2], 13); + #endif +} +#endif + +#ifndef MAGNUM_TARGET_GLES +void BufferGLTest::invalidate() { + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::invalidate_subdata::string() + std::string(" is not supported")); + + Buffer buffer; + constexpr char data[] = {2, 7, 5, 13, 25}; + buffer.setData(data, Buffer::Usage::StaticDraw); + + /* Just test that no errors are emitted */ + + buffer.invalidateSubData(3, 2); + MAGNUM_VERIFY_NO_ERROR(); + + buffer.invalidateData(); + MAGNUM_VERIFY_NO_ERROR(); +} +#endif + +}} + +CORRADE_TEST_MAIN(Magnum::Test::BufferGLTest) diff --git a/src/Test/CMakeLists.txt b/src/Test/CMakeLists.txt index 3998a58ee..d4847a633 100644 --- a/src/Test/CMakeLists.txt +++ b/src/Test/CMakeLists.txt @@ -34,4 +34,8 @@ corrade_add_test(RendererTest RendererTest.cpp LIBRARIES Magnum) corrade_add_test(ResourceManagerTest ResourceManagerTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(SwizzleTest SwizzleTest.cpp LIBRARIES MagnumMathTestLib) +if(BUILD_GL_TESTS) + corrade_add_test(BufferGLTest BufferGLTest.cpp LIBRARIES ${GL_TEST_LIBRARIES}) +endif() + set_target_properties(ResourceManagerTest PROPERTIES COMPILE_FLAGS -DCORRADE_GRACEFUL_ASSERT)