From 85bf771ea6d8d584f1c735cc963e17571ca0a0d1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 17 Apr 2023 11:54:07 +0100 Subject: First cut of instance vertices and proxy Untested outside unit test, allows the use of a glBuffer as a storage container. To be combined with a vertex array and/or mesh etc for massing drawing with glDrawElementsInstanced --- test/Jamfile.jam | 1 + test/test-instancing.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 test/test-instancing.cpp (limited to 'test') diff --git a/test/Jamfile.jam b/test/Jamfile.jam index b0eed5e..9cdcef4 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -57,6 +57,7 @@ run test-assetFactory.cpp : -- : [ sequence.insertion-sort [ glob-tree $(res) : run perf-assetFactory.cpp : -- : test-assetFactory : benchmark test ; run perf-persistence.cpp : -- : test-persistence : benchmark test ; run test-worker.cpp ; +run test-instancing.cpp : : : test ; compile test-static-enumDetails.cpp ; compile test-static-stream_support.cpp ; explicit perf-assetFactory ; diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp new file mode 100644 index 0000000..7191567 --- /dev/null +++ b/test/test-instancing.cpp @@ -0,0 +1,76 @@ +#define BOOST_TEST_MODULE instancing + +#include "testHelpers.h" +#include "testMainWindow.h" +#include "ui/applicationBase.h" +#include +#include + +#include + +BOOST_GLOBAL_FIXTURE(ApplicationBase); +BOOST_GLOBAL_FIXTURE(TestMainWindow); + +BOOST_FIXTURE_TEST_SUITE(i, InstanceVertices) + +BOOST_AUTO_TEST_CASE(createDestroy) +{ + BOOST_REQUIRE(data.data()); + BOOST_CHECK_EQUAL(0, next); + BOOST_CHECK(unused.empty()); +} + +BOOST_AUTO_TEST_CASE(storeRetreive) +{ // Read write raw buffer, not normally allowed + std::vector test(data.size()); + std::copy(test.begin(), test.end(), data.begin()); + BOOST_CHECK_EQUAL_COLLECTIONS(test.begin(), test.end(), data.begin(), data.end()); +} + +BOOST_AUTO_TEST_CASE(acquireRelease) +{ + { + auto proxy = acquire(); + *proxy = 20; + BOOST_CHECK_EQUAL(1, next); + } + BOOST_CHECK_EQUAL(1, next); + BOOST_CHECK_EQUAL(1, unused.size()); + BOOST_CHECK_EQUAL(0, unused.front()); +} + +BOOST_AUTO_TEST_CASE(acquireReleaseMove) +{ + { + auto proxy1 = acquire(); + *proxy1 = 20; + BOOST_CHECK_EQUAL(1, next); + auto proxy2 = std::move(proxy1); + *proxy2 = 40; + BOOST_CHECK_EQUAL(1, next); + } + BOOST_CHECK_EQUAL(1, next); + BOOST_CHECK_EQUAL(1, unused.size()); + BOOST_CHECK_EQUAL(0, unused.front()); +} + +BOOST_AUTO_TEST_CASE(initialize) +{ + auto proxy = acquire(5); + BOOST_CHECK_EQUAL(*proxy, 5); +} + +BOOST_AUTO_TEST_CASE(resize) +{ + constexpr auto COUNT = 500; + std::vector proxies; + std::vector expected; + for (auto n = 0; n < COUNT; n++) { + proxies.push_back(acquire(n)); + expected.emplace_back(n); + } + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), data.begin(), data.begin() + COUNT); + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), proxies.begin(), proxies.end()); +} + +BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.3 From 93f11a006b94ccecd7a1fd1dfba0adff56ae7c38 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 19 Apr 2023 00:51:35 +0100 Subject: Drop performance debug to warning and stop disabling error checking for texture save --- test/test-assetFactory.cpp | 1 - test/test-render.cpp | 3 --- test/testMainWindow.cpp | 3 ++- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'test') diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 3d79213..82543f3 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -29,7 +29,6 @@ public: FactoryFixture() : sceneRenderer {size, output} { } ~FactoryFixture() { - glDisable(GL_DEBUG_OUTPUT); auto outpath = (TMP / boost::unit_test::framework::current_test_case().full_name()).replace_extension(".tga"); std::filesystem::create_directories(outpath.parent_path()); Texture::save(outImage, outpath.c_str()); diff --git a/test/test-render.cpp b/test/test-render.cpp index 45acab5..1643068 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -86,7 +86,6 @@ BOOST_AUTO_TEST_CASE(basic) ss.camera.setView({-10, -10, 60}, glm::normalize(glm::vec3 {1, 1, -0.5F})); const TestScene scene; ss.render(scene); - glDisable(GL_DEBUG_OUTPUT); Texture::save(outImage, "/tmp/basic.tga"); } @@ -114,7 +113,6 @@ BOOST_AUTO_TEST_CASE(pointlight) }; const PointLightScene scene; ss.render(scene); - glDisable(GL_DEBUG_OUTPUT); Texture::save(outImage, "/tmp/pointlight.tga"); } @@ -141,7 +139,6 @@ BOOST_AUTO_TEST_CASE(spotlight) }; const PointLightScene scene; ss.render(scene); - glDisable(GL_DEBUG_OUTPUT); Texture::save(outImage, "/tmp/spotlight.tga"); } diff --git a/test/testMainWindow.cpp b/test/testMainWindow.cpp index 49e18f1..57e3473 100644 --- a/test/testMainWindow.cpp +++ b/test/testMainWindow.cpp @@ -12,11 +12,12 @@ TestMainWindow::TestMainWindow() : Window {1, 1, __FILE__, SDL_WINDOW_OPENGL | S (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""), type, severity, message); switch (type) { case GL_DEBUG_TYPE_ERROR: - case GL_DEBUG_TYPE_PERFORMANCE: case GL_DEBUG_TYPE_PORTABILITY: case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: BOOST_TEST_ERROR(msg.get()); + case GL_DEBUG_TYPE_PERFORMANCE: + BOOST_TEST_WARN(msg.get()); default: BOOST_TEST_MESSAGE(msg.get()); } -- cgit v1.2.3 From ac05fbbc71282b059164b51efd68ee6e372870cb Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 20 Apr 2023 20:27:43 +0100 Subject: Switch to render trees in bulk through foliage asset rendering --- test/test-assetFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 82543f3..817654b 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5)) BOOST_REQUIRE(tree_01_1_f); auto plant = std::make_shared(tree_01_1_f, Location {{-2, 2, 0}, {}}); - objects.objects.push_back(plant); + objects.objects.push_back(tree_01_1_f); render(5); } -- cgit v1.2.3 From ab5b46dbe58ae0401c24ead55a2627b9a577fc1a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 21 Apr 2023 23:52:56 +0100 Subject: Instances buffer data needs to be unmapped before use Here we change quite a bit to support mapping and unmapping the buffer as required. The instance/free referencing is still broken though. We add several instances of tree in the render. --- test/Jamfile.jam | 2 +- test/test-assetFactory.cpp | 5 ++++- test/test-instancing.cpp | 15 ++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/Jamfile.jam b/test/Jamfile.jam index 9cdcef4..1ce73b7 100644 --- a/test/Jamfile.jam +++ b/test/Jamfile.jam @@ -53,7 +53,7 @@ run test-text.cpp ; run test-enumDetails.cpp ; run test-render.cpp : -- : test-assetFactory : test ; run test-glContextBhvr.cpp ; -run test-assetFactory.cpp : -- : [ sequence.insertion-sort [ glob-tree $(res) : *.* ] fixtures/rgb.txt ] : test ; +run test-assetFactory.cpp : -- : [ sequence.insertion-sort [ glob-tree $(res) : *.* ] fixtures/rgb.txt test-instancing ] : test ; run perf-assetFactory.cpp : -- : test-assetFactory : benchmark test ; run perf-persistence.cpp : -- : test-persistence : benchmark test ; run test-worker.cpp ; diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 817654b..82a1825 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -107,7 +107,10 @@ BOOST_AUTO_TEST_CASE(foliage, *boost::unit_test::timeout(5)) auto tree_01_1_f = std::dynamic_pointer_cast(tree_01_1); BOOST_REQUIRE(tree_01_1_f); - auto plant = std::make_shared(tree_01_1_f, Location {{-2, 2, 0}, {}}); + auto plant1 = std::make_shared(tree_01_1_f, Location {{-2, 2, 0}, {0, 0, 0}}); + auto plant2 = std::make_shared(tree_01_1_f, Location {{3, -4, 0}, {0, 1, 0}}); + auto plant3 = std::make_shared(tree_01_1_f, Location {{-2, -4, 0}, {0, 2, 0}}); + auto plant4 = std::make_shared(tree_01_1_f, Location {{3, 2, 0}, {0, 3, 0}}); objects.objects.push_back(tree_01_1_f); render(5); diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index 7191567..2eb3647 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -15,16 +15,21 @@ BOOST_FIXTURE_TEST_SUITE(i, InstanceVertices) BOOST_AUTO_TEST_CASE(createDestroy) { - BOOST_REQUIRE(data.data()); + BOOST_CHECK(!data); + map(); + BOOST_REQUIRE(data); BOOST_CHECK_EQUAL(0, next); BOOST_CHECK(unused.empty()); + unmap(); + BOOST_CHECK(!data); } BOOST_AUTO_TEST_CASE(storeRetreive) { // Read write raw buffer, not normally allowed - std::vector test(data.size()); - std::copy(test.begin(), test.end(), data.begin()); - BOOST_CHECK_EQUAL_COLLECTIONS(test.begin(), test.end(), data.begin(), data.end()); + std::vector test(capacity); + map(); + std::copy(test.begin(), test.end(), data); + BOOST_CHECK_EQUAL_COLLECTIONS(test.begin(), test.end(), data, data + capacity); } BOOST_AUTO_TEST_CASE(acquireRelease) @@ -69,7 +74,7 @@ BOOST_AUTO_TEST_CASE(resize) proxies.push_back(acquire(n)); expected.emplace_back(n); } - BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), data.begin(), data.begin() + COUNT); + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), data, data + COUNT); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), proxies.begin(), proxies.end()); } -- cgit v1.2.3 From b8889129c6c2b747ff771b711cfbbf91bca93bb6 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 22 Apr 2023 11:44:38 +0100 Subject: Fix the instancing maintenance --- test/test-instancing.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index 2eb3647..8837071 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -1,10 +1,12 @@ #define BOOST_TEST_MODULE instancing +#include "stream_support.hpp" #include "testHelpers.h" #include "testMainWindow.h" #include "ui/applicationBase.h" #include #include +#include #include @@ -20,28 +22,25 @@ BOOST_AUTO_TEST_CASE(createDestroy) BOOST_REQUIRE(data); BOOST_CHECK_EQUAL(0, next); BOOST_CHECK(unused.empty()); + BOOST_CHECK(index.empty()); unmap(); BOOST_CHECK(!data); } -BOOST_AUTO_TEST_CASE(storeRetreive) -{ // Read write raw buffer, not normally allowed - std::vector test(capacity); - map(); - std::copy(test.begin(), test.end(), data); - BOOST_CHECK_EQUAL_COLLECTIONS(test.begin(), test.end(), data, data + capacity); -} - BOOST_AUTO_TEST_CASE(acquireRelease) { { auto proxy = acquire(); *proxy = 20; BOOST_CHECK_EQUAL(1, next); + BOOST_REQUIRE_EQUAL(1, index.size()); + BOOST_CHECK_EQUAL(0, index.front()); + BOOST_CHECK(unused.empty()); } - BOOST_CHECK_EQUAL(1, next); + BOOST_CHECK_EQUAL(0, next); BOOST_CHECK_EQUAL(1, unused.size()); BOOST_CHECK_EQUAL(0, unused.front()); + BOOST_CHECK_EQUAL(1, index.size()); } BOOST_AUTO_TEST_CASE(acquireReleaseMove) @@ -54,9 +53,10 @@ BOOST_AUTO_TEST_CASE(acquireReleaseMove) *proxy2 = 40; BOOST_CHECK_EQUAL(1, next); } - BOOST_CHECK_EQUAL(1, next); + BOOST_CHECK_EQUAL(0, next); BOOST_CHECK_EQUAL(1, unused.size()); BOOST_CHECK_EQUAL(0, unused.front()); + BOOST_CHECK_EQUAL(1, index.size()); } BOOST_AUTO_TEST_CASE(initialize) @@ -78,4 +78,89 @@ BOOST_AUTO_TEST_CASE(resize) BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), proxies.begin(), proxies.end()); } +BOOST_AUTO_TEST_CASE(shuffle) +{ + std::vector proxies; + BOOST_CHECK_EQUAL(0, proxies.emplace_back(acquire(0))); + BOOST_CHECK_EQUAL(1, proxies.emplace_back(acquire(1))); + BOOST_CHECK_EQUAL(2, proxies.emplace_back(acquire(2))); + BOOST_CHECK_EQUAL(3, proxies.emplace_back(acquire(3))); + BOOST_CHECK_EQUAL(4, next); + BOOST_CHECK_EQUAL(data + 0, proxies[0].get()); + BOOST_CHECK_EQUAL(data + 1, proxies[1].get()); + BOOST_CHECK_EQUAL(data + 2, proxies[2].get()); + BOOST_CHECK_EQUAL(data + 3, proxies[3].get()); + BOOST_CHECK(unused.empty()); + BOOST_REQUIRE_EQUAL(4, index.size()); + BOOST_CHECK_EQUAL(0, index[0]); + BOOST_CHECK_EQUAL(1, index[1]); + BOOST_CHECK_EQUAL(2, index[2]); + BOOST_CHECK_EQUAL(3, index[3]); + // Remove 1, 3 moves to [1] + proxies.erase(proxies.begin() + 1); + BOOST_REQUIRE_EQUAL(4, index.size()); + BOOST_REQUIRE_EQUAL(1, unused.size()); + BOOST_CHECK_EQUAL(1, unused[0]); + BOOST_CHECK_EQUAL(data + 0, proxies[0].get()); + BOOST_CHECK_EQUAL(data + 2, proxies[1].get()); + BOOST_CHECK_EQUAL(data + 1, proxies[2].get()); + // Remove 1, 2 moves to [1] + proxies.erase(proxies.begin() + 1); + BOOST_REQUIRE_EQUAL(4, index.size()); + BOOST_REQUIRE_EQUAL(2, unused.size()); + BOOST_CHECK_EQUAL(1, unused[0]); + BOOST_CHECK_EQUAL(2, unused[1]); + BOOST_CHECK_EQUAL(data + 0, proxies[0].get()); + BOOST_CHECK_EQUAL(data + 1, proxies[1].get()); + // Add new, takes 2 at [2] + BOOST_CHECK_EQUAL(4, proxies.emplace_back(acquire(4))); + BOOST_REQUIRE_EQUAL(4, index.size()); + BOOST_REQUIRE_EQUAL(1, unused.size()); + BOOST_CHECK_EQUAL(1, unused[0]); + BOOST_CHECK_EQUAL(data + 0, proxies[0].get()); + BOOST_CHECK_EQUAL(data + 1, proxies[1].get()); + BOOST_CHECK_EQUAL(data + 2, proxies[2].get()); +} + +BOOST_DATA_TEST_CASE(shuffle_random, boost::unit_test::data::xrange(0, 10), x) +{ + std::ignore = x; + std::mt19937 gen(std::random_device {}()); + std::map::InstanceProxy> proxies; + const std::string_view actions = "aaaaaaaarararrraarrrararararaarrrarararararararararraarrrraaaarararaararar"; + int n {}; + for (const auto action : actions) { + switch (action) { + case 'a': + BOOST_REQUIRE_EQUAL(n, proxies.emplace(n, acquire(n)).first->second); + n++; + break; + case 'r': + BOOST_REQUIRE(!proxies.empty()); + auto e = std::next(proxies.begin(), + std::uniform_int_distribution<> {0, static_cast(proxies.size() - 1)}(gen)); + proxies.erase(e); + break; + } + + BOOST_REQUIRE_EQUAL(next, proxies.size()); + for (const auto & [n, p] : proxies) { + BOOST_REQUIRE_EQUAL(n, p); + } + std::set iused; + for (size_t i {}; i < index.size(); i++) { + if (std::find(unused.begin(), unused.end(), i) == unused.end()) { + iused.emplace(index[i]); + } + } + BOOST_TEST_CONTEXT(index) { + BOOST_REQUIRE_EQUAL(iused.size(), next); + if (!iused.empty()) { + BOOST_REQUIRE_EQUAL(*iused.begin(), 0); + BOOST_REQUIRE_EQUAL(*iused.rbegin(), next - 1); + } + } + } +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.3 From bcd0e98739974248e6d29f72e8b281e21fd59657 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 22 Apr 2023 13:17:05 +0100 Subject: Test instancing automatic unmap when count is called, add some nodiscard --- test/test-instancing.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index 8837071..70b20fa 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -50,8 +50,9 @@ BOOST_AUTO_TEST_CASE(acquireReleaseMove) *proxy1 = 20; BOOST_CHECK_EQUAL(1, next); auto proxy2 = std::move(proxy1); - *proxy2 = 40; + proxy2 = 40; BOOST_CHECK_EQUAL(1, next); + BOOST_CHECK_EQUAL(data[0], 40); } BOOST_CHECK_EQUAL(0, next); BOOST_CHECK_EQUAL(1, unused.size()); @@ -59,10 +60,26 @@ BOOST_AUTO_TEST_CASE(acquireReleaseMove) BOOST_CHECK_EQUAL(1, index.size()); } +BOOST_AUTO_TEST_CASE(autoMapUnmap) +{ + { + auto proxy = acquire(); + BOOST_CHECK(data); + std::ignore = bufferName(); + BOOST_CHECK(data); + BOOST_CHECK_EQUAL(1, count()); + BOOST_CHECK(!data); + } + BOOST_CHECK_EQUAL(0, count()); +} + BOOST_AUTO_TEST_CASE(initialize) { auto proxy = acquire(5); + const auto & constProxy = proxy; BOOST_CHECK_EQUAL(*proxy, 5); + BOOST_CHECK_EQUAL(*constProxy, 5); + BOOST_CHECK_EQUAL(constProxy.get(), constProxy.get()); } BOOST_AUTO_TEST_CASE(resize) -- cgit v1.2.3 From 59d85f9b87fc82b52f2c7438e38768aeddc3cc87 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 22 Apr 2023 14:56:08 +0100 Subject: Don't fill the instances unused vector unnecessarily --- test/test-instancing.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/test-instancing.cpp b/test/test-instancing.cpp index 70b20fa..c743ce0 100644 --- a/test/test-instancing.cpp +++ b/test/test-instancing.cpp @@ -38,9 +38,8 @@ BOOST_AUTO_TEST_CASE(acquireRelease) BOOST_CHECK(unused.empty()); } BOOST_CHECK_EQUAL(0, next); - BOOST_CHECK_EQUAL(1, unused.size()); - BOOST_CHECK_EQUAL(0, unused.front()); - BOOST_CHECK_EQUAL(1, index.size()); + BOOST_CHECK(unused.empty()); + BOOST_CHECK(index.empty()); } BOOST_AUTO_TEST_CASE(acquireReleaseMove) @@ -55,9 +54,8 @@ BOOST_AUTO_TEST_CASE(acquireReleaseMove) BOOST_CHECK_EQUAL(data[0], 40); } BOOST_CHECK_EQUAL(0, next); - BOOST_CHECK_EQUAL(1, unused.size()); - BOOST_CHECK_EQUAL(0, unused.front()); - BOOST_CHECK_EQUAL(1, index.size()); + BOOST_CHECK(unused.empty()); + BOOST_CHECK(index.empty()); } BOOST_AUTO_TEST_CASE(autoMapUnmap) -- cgit v1.2.3