Skip to content

Commit

Permalink
#5912: IGeometryStore API is covered now
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Mar 5, 2022
1 parent 9d6ed58 commit 4af6599
Showing 1 changed file with 131 additions and 13 deletions.
144 changes: 131 additions & 13 deletions test/GeometryStore.cpp
Expand Up @@ -25,6 +25,9 @@ class NullSyncObjectProvider final :
}
};

namespace
{

inline MeshVertex createNthVertex(int n, int id, std::size_t size)
{
auto offset = static_cast<double>(n + size * id);
Expand Down Expand Up @@ -92,6 +95,19 @@ inline void verifyAllocation(render::IGeometryStore& store, render::IGeometrySto
}
}

struct Allocation
{
render::IGeometryStore::Slot slot;
std::vector<MeshVertex> vertices;
std::vector<unsigned int> indices;

bool operator<(const Allocation& other) const
{
return slot < other.slot;
}
};

}

TEST(GeometryStore, AllocateAndDeallocate)
{
Expand All @@ -114,22 +130,10 @@ TEST(GeometryStore, AllocateAndDeallocate)
}
}

TEST(GeometryStore, SetData)
TEST(GeometryStore, UpdateData)
{
render::GeometryStore store(NullSyncObjectProvider::Instance());

struct Allocation
{
render::IGeometryStore::Slot slot;
std::vector<MeshVertex> vertices;
std::vector<unsigned int> indices;

bool operator<(const Allocation& other) const
{
return slot < other.slot;
}
};

std::set<Allocation> allocations;

// Allocate 10 slots of various sizes, store some data in there
Expand Down Expand Up @@ -175,6 +179,120 @@ TEST(GeometryStore, SetData)
}
}

TEST(GeometryStore, UpdateSubData)
{
render::GeometryStore store(NullSyncObjectProvider::Instance());

std::set<Allocation> allocations;

// Allocate 10 slots of various sizes, store some data in there
auto margin = 13;

for (auto i = 0; i < 10; ++i)
{
auto vertices = generateVertices(13, 17 * 20);
auto indices = generateIndices(vertices);

auto slot = store.allocateSlot(vertices.size() + margin, indices.size() + margin);
EXPECT_NE(slot, std::numeric_limits<render::IGeometryStore::Slot>::max()) << "Invalid slot";

// We locally keep track of what the data should look like in the store
std::vector<MeshVertex> localVertexCopy(vertices.size());
std::vector<unsigned int> localIndexCopy(indices.size());

// Upload part of the data (with some increasing offset)
for (auto offset = 0; offset < margin; ++offset)
{
EXPECT_NO_THROW(store.updateSubData(slot, offset, vertices, offset, indices));

// Update our local copy accordingly
localVertexCopy.resize(vertices.size() + offset);
localIndexCopy.resize(indices.size() + offset);

std::copy(vertices.begin(), vertices.end(), localVertexCopy.begin() + offset);
std::copy(indices.begin(), indices.end(), localIndexCopy.begin() + offset);

verifyAllocation(store, slot, localVertexCopy, localIndexCopy);
}

// Finally, upload the whole data
store.updateData(slot, vertices, indices);

allocations.emplace(Allocation{ slot, vertices, indices });

// Verify the data after each round, it should not affect the other data
for (auto allocation : allocations)
{
verifyAllocation(store, allocation.slot, allocation.vertices, allocation.indices);
}
}

// Verify the data
for (auto allocation : allocations)
{
verifyAllocation(store, allocation.slot, allocation.vertices, allocation.indices);
}

// Now de-allocate one slot after the other and verify the remaining ones
while (!allocations.empty())
{
auto slot = allocations.begin()->slot;
allocations.erase(allocations.begin());

EXPECT_NO_THROW(store.deallocateSlot(slot));

// Verify the remaining slots, they should still be intact
for (auto allocation : allocations)
{
verifyAllocation(store, allocation.slot, allocation.vertices, allocation.indices);
}
}
}

TEST(GeometryStore, ResizeData)
{
render::GeometryStore store(NullSyncObjectProvider::Instance());

// Allocate a few dummy slots
store.allocateSlot(17, 27);
store.allocateSlot(31, 67);
store.allocateSlot(5, 37);

// Generate an indexed vertex set
auto vertices = generateVertices(13, 17 * 20);
auto indices = generateIndices(vertices);

auto slot = store.allocateSlot(vertices.size(), indices.size());
EXPECT_NE(slot, std::numeric_limits<render::IGeometryStore::Slot>::max()) << "Invalid slot";

// Store everything into the buffer
store.updateData(slot, vertices, indices);

// We locally keep track of what the data should look like in the store
std::vector<MeshVertex> localVertexCopy = vertices;
std::vector<unsigned int> localIndexCopy = indices;

// Reduce the data in the allocation, step by step
auto newVertexSize = localVertexCopy.size();
auto newIndexSize = localIndexCopy.size();

auto steps = std::min(newIndexSize, newVertexSize);
EXPECT_GT(steps, 4) << "Too few data elements";
steps -= 4;

for (auto i = 0; i < steps; ++i)
{
// Cut off one index at the end
// Keep the vertex buffer intact, we don't want out-of-bounds errors
localIndexCopy.resize(localIndexCopy.size() - 1);
--newVertexSize;

EXPECT_NO_THROW(store.resizeData(slot, newVertexSize, localIndexCopy.size()));

verifyAllocation(store, slot, localVertexCopy, localIndexCopy);
}
}

TEST(GeometryStore, SyncObjectAcquisition)
{
render::GeometryStore store(NullSyncObjectProvider::Instance());
Expand Down

0 comments on commit 4af6599

Please sign in to comment.