VertexData refactor

This commit is contained in:
Dynamitos
2025-04-14 22:26:33 +02:00
parent d0899355c5
commit 47360714a5
10 changed files with 76 additions and 63 deletions
+7 -5
View File
@@ -1,14 +1,16 @@
#pragma once
#include "Math/AABB.h"
namespace Seele {
struct PoolRange {
uint32 offset;
uint32 size;
};
struct MeshData {
AABB bounding;
uint32 numMeshlets = 0;
uint32 meshletOffset = 0;
PoolRange meshletRange;
// offset into the global index buffer
uint32 firstIndex = 0;
// number of indices in the global index buffer
uint32 numIndices = 0;
PoolRange indicesRange;
};
struct InstanceData {
Matrix4 transformMatrix;
+2 -2
View File
@@ -232,8 +232,8 @@ void BasePass::render() {
command->bindIndexBuffer(vertexData->getIndexBuffer());
for (const auto& meshData : drawCall.instanceMeshData) {
// all meshlets of a mesh share the same indices offset
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
vertexData->getIndicesOffset(meshData.meshletOffset), 0);
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
vertexData->getIndicesOffset(meshData.meshletRange.offset), 0);
}
}
}
@@ -124,8 +124,8 @@ void CachedDepthPass::render() {
uint32 inst = drawCall.offsets.instanceOffset;
for (const auto& meshData : drawCall.instanceMeshData) {
// all meshlets of a mesh share the same indices offset
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
}
}
}
@@ -195,8 +195,8 @@ void DepthCullingPass::render() {
uint32 inst = drawCall.offsets.instanceOffset;
for (const auto& meshData : drawCall.instanceMeshData) {
// all meshlets of a mesh share the same indices offset
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex,
vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
command->drawIndexed(meshData.indicesRange.size, 1, meshData.indicesRange.offset,
vertexData->getIndicesOffset(meshData.meshletRange.offset), inst++);
}
}
}
+3 -3
View File
@@ -58,8 +58,8 @@ void StaticMeshVertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
uint64 numVertices;
{
std::unique_lock l(vertexDataLock);
offset = meshOffsets[id];
numVertices = meshVertexCounts[id];
offset = registeredMeshes[id].vertexOffset;
numVertices = registeredMeshes[id].vertexCount;
}
Array<TexCoordType> tex[MAX_TEXCOORDS];
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
@@ -89,7 +89,7 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
uint64 offset;
{
std::unique_lock l(vertexDataLock);
offset = meshOffsets[id];
offset = registeredMeshes[id].vertexOffset;
}
Array<TexCoordType> tex[MAX_TEXCOORDS];
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
+40 -31
View File
@@ -58,7 +58,7 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo
}
BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()];
matInstanceData.materialInstance = referencedInstance;
for (const auto& data : meshData[mesh->id]) {
for (const auto& data : registeredMeshes[mesh->id].meshData) {
if (mat->hasTransparency()) {
auto params = referencedInstance->getMaterialOffsets();
transparentData.add(TransparentDraw{
@@ -140,6 +140,7 @@ void VertexData::createDescriptors() {
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
std::unique_lock l(vertexDataLock);
RegisteredMesh& mesh = registeredMeshes[id];
uint32 numChunks = (loadedMeshlets.size() + 2047) / 2048;
for (uint32 chunkIdx = 0; chunkIdx < numChunks; ++chunkIdx) {
uint32 meshletOffset = (uint32)meshlets.size();
@@ -160,33 +161,40 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
meshlets.add(MeshletDescription{
.bounding = m.boundingBox, //.toSphere(),
.vertexCount = m.numVertices,
.primitiveCount = m.numPrimitives,
.vertexOffset = vertexOffset,
.primitiveOffset = primitiveOffset,
.vertexIndices =
{
.offset = vertexOffset,
.size = m.numVertices,
},
.primitiveIndices =
{
.offset = primitiveOffset,
.size = m.numPrimitives,
},
.color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX),
.indicesOffset = (uint32)meshOffsets[id],
.indicesOffset = (uint32)registeredMeshes[id].indicesRange.offset,
});
}
meshData[id].add(MeshData{
registeredMeshes[id].meshData.add(MeshData{
.bounding = meshAABB, //.toSphere(),
.numMeshlets = numMeshlets,
.meshletOffset = meshletOffset,
.meshletRange =
{
.offset = meshletOffset,
.size = numMeshlets,
},
});
}
// todo: in case of a index split for 16 bit, do something here
meshData[id][0].firstIndex = (uint32)indices.size();
meshData[id][0].numIndices = (uint32)loadedIndices.size();
registeredMeshes[id].meshData[0].indicesRange = {
.offset = (uint32)indices.size(),
.size = (uint32)loadedIndices.size(),
};
indices.resize(indices.size() + loadedIndices.size());
std::memcpy(indices.data() + meshData[id][0].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
std::memcpy(indices.data() + registeredMeshes[id].meshData[0].indicesRange.offset, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
}
void VertexData::updateMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets) {
uint32 numMeshlets = 0;
for (const auto& dat : meshData[id]) {
numMeshlets += dat.numMeshlets;
}
int32 difference = meshlets.size() - numMeshlets;
}
void VertexData::commitMeshes() {
@@ -235,9 +243,10 @@ void VertexData::commitMeshes() {
MeshId VertexData::allocateVertexData(uint64 numVertices) {
std::unique_lock l(vertexDataLock);
MeshId res{idCounter++};
meshOffsets.add(head);
meshVertexCounts.add(numVertices);
meshData.add({});
registeredMeshes.add({
.vertexOffset = head,
.vertexCount = numVertices,
});
head += numVertices;
if (head > verticesAllocated) {
verticesAllocated = 2 * head; // double capacity
@@ -250,21 +259,21 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) {
void VertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
std::unique_lock l(vertexDataLock);
Array<Meshlet> out;
for (uint32 n = 0; n < meshData[id].size(); ++n) {
MeshData data = meshData[id][n];
for (size_t i = 0; i < data.numMeshlets; ++i) {
MeshletDescription& desc = meshlets[i + data.meshletOffset];
for (uint32 n = 0; n < registeredMeshes[id].meshData.size(); ++n) {
MeshData data = registeredMeshes[id].meshData[n];
for (size_t i = 0; i < data.meshletRange.size; ++i) {
MeshletDescription& desc = meshlets[i + data.meshletRange.offset];
Meshlet m;
std::memcpy(m.uniqueVertices, &vertexIndices[desc.vertexOffset], desc.vertexCount * sizeof(uint32));
std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveOffset], desc.primitiveCount * 3 * sizeof(uint8));
m.numPrimitives = desc.primitiveCount;
m.numVertices = desc.vertexCount;
std::memcpy(m.uniqueVertices, &vertexIndices[desc.vertexIndices.offset], desc.vertexIndices.size * sizeof(uint32));
std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveIndices.offset], desc.primitiveIndices.size * 3 * sizeof(uint8));
m.numPrimitives = desc.primitiveIndices.size;
m.numVertices = desc.vertexIndices.size;
m.boundingBox = desc.bounding;
out.add(std::move(m));
}
}
Array<uint32> ind(meshData[id][0].numIndices);
std::memcpy(ind.data(), &indices[meshData[id][0].firstIndex], meshData[id][0].numIndices * sizeof(uint32));
Array<uint32> ind(registeredMeshes[id].meshData[0].indicesRange.size);
std::memcpy(ind.data(), &indices[registeredMeshes[id].meshData[0].indicesRange.offset], registeredMeshes[id].meshData[0].indicesRange.size * sizeof(uint32));
Serialization::save(buffer, out);
Serialization::save(buffer, ind);
}
@@ -360,14 +369,14 @@ void VertexData::destroy() {
vertexIndicesBuffer = nullptr;
primitiveIndicesBuffer = nullptr;
indexBuffer = nullptr;
meshData.clear();
registeredMeshes.clear();
materialData.clear();
}
uint32 VertexData::addCullingMapping(MeshId id) {
uint32 result = (uint32)meshletCount;
for (const auto& md : getMeshData(id)) {
meshletCount += md.numMeshlets;
meshletCount += md.meshletRange.size;
}
return result;
}
+16 -14
View File
@@ -61,8 +61,8 @@ class VertexData {
void updateMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
void commitMeshes();
MeshId allocateVertexData(uint64 numVertices);
uint64 getMeshOffset(MeshId id) const { return meshOffsets[id]; }
uint64 getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; }
uint64 getMeshOffset(MeshId id) const { return registeredMeshes[id].vertexOffset; }
uint64 getMeshVertexCount(MeshId id) { return registeredMeshes[id].vertexCount; }
virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer);
virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer);
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
@@ -76,7 +76,7 @@ class VertexData {
const Array<MaterialData>& getMaterialData() const { return materialData; }
const Array<TransparentDraw>& getTransparentData() const { return transparentData; }
const Array<Gfx::PBottomLevelAS>& getRayTracingData() const { return rayTracingScene; }
const Array<MeshData>& getMeshData(MeshId id) const { return meshData[id]; }
const Array<MeshData>& getMeshData(MeshId id) const { return registeredMeshes[id].meshData; }
void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) { dataToBuild.add(blas); }
uint32 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; }
uint64 getNumInstances() const { return instanceData.size(); }
@@ -96,14 +96,10 @@ class VertexData {
VertexData();
struct MeshletDescription {
AABB bounding;
// number of relevant entries in the vertexIndices array
uint32 vertexCount;
// number of relevant entries in the primitiveIndices array
uint32 primitiveCount;
// starting offset into the vertexIndices array
uint32 vertexOffset;
// starting offset into the primitiveIndices array
uint32 primitiveOffset;
// range into vertexIndices array
PoolRange vertexIndices;
// range into primitiveIndices array
PoolRange primitiveIndices;
Vector color;
// gets added to vertex indices so that they reference the global mesh bool
uint32 indicesOffset = 0;
@@ -114,10 +110,16 @@ class VertexData {
Array<TransparentDraw> transparentData;
std::mutex vertexDataLock;
struct RegisteredMesh
{
// each mesh id can have multiple meshdata, in case it needs to be split for having too many meshlets
Array<Array<MeshData>> meshData;
Array<uint64> meshOffsets;
Array<uint64> meshVertexCounts;
Array<MeshData> meshData;
uint64 vertexOffset;
uint64 vertexCount;
PoolRange meshletRange;
PoolRange indicesRange;
};
Array<RegisteredMesh> registeredMeshes;
Array<MeshletDescription> meshlets;
Array<uint8> primitiveIndices;
+1 -1
View File
@@ -3,7 +3,7 @@
#include "Enums.h"
#include "Graphics/Enums.h"
#include <fmt/format.h>
#include <vma/vk_mem_alloc.h>
#include <vk_mem_alloc.h>
using namespace Seele;
using namespace Seele::Vulkan;
+2 -2
View File
@@ -26,8 +26,8 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI
MeshData meshData = vertexData->getMeshData(createInfo.mesh->id)[0];
vertexOffset = vertexData->getMeshOffset(createInfo.mesh->id) * sizeof(Vector);
vertexCount = vertexData->getMeshVertexCount(createInfo.mesh->id);
indexOffset = meshData.firstIndex * sizeof(uint32);
primitiveCount = meshData.numIndices / 3;
indexOffset = meshData.indicesRange.offset * sizeof(uint32);
primitiveCount = meshData.indicesRange.size / 3;
// todo: compact
}