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