From 47360714a5596c6db7aa36f3d2c8d3c49724d1c8 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Mon, 14 Apr 2025 22:26:33 +0200 Subject: [PATCH] VertexData refactor --- external/vcpkg | 2 +- src/Engine/Graphics/MeshData.h | 12 ++-- src/Engine/Graphics/RenderPass/BasePass.cpp | 4 +- .../Graphics/RenderPass/CachedDepthPass.cpp | 4 +- .../Graphics/RenderPass/DepthCullingPass.cpp | 4 +- src/Engine/Graphics/StaticMeshVertexData.cpp | 6 +- src/Engine/Graphics/VertexData.cpp | 71 +++++++++++-------- src/Engine/Graphics/VertexData.h | 30 ++++---- src/Engine/Graphics/Vulkan/Buffer.cpp | 2 +- src/Engine/Graphics/Vulkan/RayTracing.cpp | 4 +- 10 files changed, 76 insertions(+), 63 deletions(-) diff --git a/external/vcpkg b/external/vcpkg index f9a99aa..0bf1354 160000 --- a/external/vcpkg +++ b/external/vcpkg @@ -1 +1 @@ -Subproject commit f9a99aa79c1309001e36572fa42d7d8edebfc451 +Subproject commit 0bf1354d6704ec797acea686d0250afc4036a082 diff --git a/src/Engine/Graphics/MeshData.h b/src/Engine/Graphics/MeshData.h index d6206ae..e15f0c1 100644 --- a/src/Engine/Graphics/MeshData.h +++ b/src/Engine/Graphics/MeshData.h @@ -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; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index cc56070..a05a8e3 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -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); } } } diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index b648efd..bcf01a4 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -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++); } } } diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index dec7386..9a4c1c4 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -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++); } } } diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 7b43ef5..c82b27c 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -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 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 tex[MAX_TEXCOORDS]; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 896297e..7a84b17 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -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 loadedIndices, Array 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 loadedIndices, Array 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 indices, Array 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 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 ind(meshData[id][0].numIndices); - std::memcpy(ind.data(), &indices[meshData[id][0].firstIndex], meshData[id][0].numIndices * sizeof(uint32)); + Array 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; } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 243fe84..f7ef52c 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -61,8 +61,8 @@ class VertexData { void updateMesh(MeshId id, Array indices, Array 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& getMaterialData() const { return materialData; } const Array& getTransparentData() const { return transparentData; } const Array& getRayTracingData() const { return rayTracingScene; } - const Array& getMeshData(MeshId id) const { return meshData[id]; } + const Array& 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 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> meshData; - Array meshOffsets; - Array meshVertexCounts; + Array meshData; + uint64 vertexOffset; + uint64 vertexCount; + PoolRange meshletRange; + PoolRange indicesRange; + }; + Array registeredMeshes; Array meshlets; Array primitiveIndices; diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index ca1761d..dea4524 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -3,7 +3,7 @@ #include "Enums.h" #include "Graphics/Enums.h" #include -#include +#include using namespace Seele; using namespace Seele::Vulkan; diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index dfd6b0d..6962da2 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -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 }