Files
Seele/src/Engine/Graphics/VertexData.cpp
T

238 lines
7.8 KiB
C++
Raw Normal View History

2023-10-24 15:01:09 +02:00
#include "VertexData.h"
2023-10-31 23:44:46 +01:00
#include "Graphics/Enums.h"
#include "Graphics/Initializer.h"
2023-10-24 15:01:09 +02:00
#include "Material/Material.h"
#include "Graphics/Graphics.h"
2023-10-26 18:37:29 +02:00
#include "Graphics/Descriptor.h"
#include "Component/Mesh.h"
2023-11-15 17:42:57 +01:00
#include "Graphics/Shader.h"
2023-10-24 15:01:09 +02:00
using namespace Seele;
2023-11-06 14:47:21 +01:00
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
2023-10-31 17:55:30 +01:00
2023-10-24 15:01:09 +02:00
void VertexData::resetMeshData()
{
materialData.clear();
2023-10-31 16:16:23 +01:00
if (dirty)
{
updateBuffers();
2023-11-08 23:27:21 +01:00
dirty = false;
2023-10-31 16:16:23 +01:00
}
2023-10-24 15:01:09 +02:00
}
2023-11-06 14:47:21 +01:00
void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh)
2023-10-24 15:01:09 +02:00
{
2023-11-06 14:47:21 +01:00
PMaterial mat = mesh->referencedMaterial->getHandle()->getBaseMaterial();
2023-10-24 15:01:09 +02:00
MaterialData& matData = materialData[mat->getName()];
2023-11-08 23:27:21 +01:00
matData.material = mat;
2023-11-06 14:47:21 +01:00
MaterialInstanceData& matInstanceData = matData.instances[mesh->referencedMaterial->getHandle()->getId()];
2023-10-24 15:01:09 +02:00
matInstanceData.meshes.add(MeshInstanceData{
2023-11-06 14:47:21 +01:00
.id = mesh->id,
2023-10-24 15:01:09 +02:00
.instance = InstanceData {
2023-11-13 13:23:16 +01:00
.transformMatrix = transform.toMatrix(),
},
.indexBuffer = mesh->indexBuffer,
2023-10-24 15:01:09 +02:00
});
2023-11-11 22:39:17 +01:00
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
matInstanceData.materialInstance->updateDescriptor();
2023-11-09 22:15:51 +01:00
matInstanceData.numMeshes += meshData[mesh->id].size();
2023-10-24 15:01:09 +02:00
}
2023-11-10 19:18:09 +01:00
void VertexData::createDescriptors()
{
instanceDataLayout->reset();
for (const auto& [_, mat] : materialData)
{
for (auto& [_, matInst] : mat.instances)
{
Array<InstanceData> instanceData;
Array<MeshData> meshes;
for (auto& inst : matInst.meshes)
{
inst.meshes = 0;
for (const auto& mesh : meshData[inst.id])
{
instanceData.add(inst.instance);
meshes.add(mesh);
inst.meshes++;
}
}
matInst.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = sizeof(InstanceData) * instanceData.size(),
.data = (uint8*)instanceData.data(),
},
2023-11-15 17:42:57 +01:00
.numElements = instanceData.size(),
.dynamic = false,
2023-11-10 19:18:09 +01:00
});
matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet();
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
if (graphics->supportMeshShading())
{
matInst.meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = sizeof(MeshData) * meshes.size(),
.data = (uint8*)meshes.data(),
},
2023-11-15 17:42:57 +01:00
.numElements = meshes.size(),
.dynamic = false,
2023-11-10 19:18:09 +01:00
});
matInst.descriptorSet->updateBuffer(1, matInst.meshDataBuffer);
matInst.descriptorSet->updateBuffer(2, meshletBuffer);
matInst.descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
matInst.descriptorSet->updateBuffer(4, vertexIndicesBuffer);
}
matInst.descriptorSet->writeChanges();
matInst.numMeshes = meshes.size();
}
}
}
2023-10-31 17:55:30 +01:00
void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
2023-10-31 16:16:23 +01:00
{
meshData[id].clear();
2023-10-31 17:55:30 +01:00
uint32 currentMesh = 0;
while (currentMesh < loadedMeshlets.size())
2023-10-31 16:16:23 +01:00
{
2023-10-31 17:55:30 +01:00
uint32 numMeshlets = std::min<uint32>(512, loadedMeshlets.size() - currentMesh);
uint32 meshletOffset = meshlets.size();
2023-10-31 16:16:23 +01:00
for (uint32 i = 0; i < numMeshlets; ++i)
{
2023-10-31 17:55:30 +01:00
Meshlet& m = loadedMeshlets[currentMesh + i];
uint32 vertexOffset = vertexIndices.size();
vertexIndices.resize(vertexOffset + m.numVertices);
2023-11-06 14:47:21 +01:00
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices.data(), m.numVertices * sizeof(uint32));
2023-10-31 17:55:30 +01:00
uint32 primitiveOffset = primitiveIndices.size();
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
2023-11-06 14:47:21 +01:00
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout.data(), m.numPrimitives * 3 * sizeof(uint8));
2023-10-31 17:55:30 +01:00
meshlets.add(MeshletDescription{
2023-10-31 16:16:23 +01:00
.boundingBox = MeshletAABB(),
.vertexCount = m.numVertices,
.primitiveCount = m.numPrimitives,
2023-10-31 17:55:30 +01:00
.vertexOffset = vertexOffset,
.primitiveOffset = primitiveOffset,
2023-10-31 16:16:23 +01:00
});
}
2023-10-31 17:55:30 +01:00
meshData[id].add(MeshData{
.numMeshlets = numMeshlets,
.meshletOffset = meshletOffset,
.indicesOffset = static_cast<uint32>(meshOffsets[id]),
2023-11-10 19:18:09 +01:00
});
2023-10-31 17:55:30 +01:00
currentMesh += numMeshlets;
2023-10-31 16:16:23 +01:00
}
2023-11-10 19:18:09 +01:00
meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
2023-11-01 23:12:30 +01:00
.sourceData = {
2023-10-31 23:44:46 +01:00
.size = sizeof(MeshletDescription) * meshlets.size(),
.data = (uint8*)meshlets.data()
},
2023-11-15 17:42:57 +01:00
.numElements = meshlets.size(),
2023-11-05 10:36:01 +01:00
.dynamic = true,
2023-11-15 17:42:57 +01:00
});
2023-11-10 19:18:09 +01:00
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
2023-11-01 23:12:30 +01:00
.sourceData = {
2023-10-31 23:44:46 +01:00
.size = sizeof(uint32) * vertexIndices.size(),
.data = (uint8*)vertexIndices.data(),
},
2023-11-15 17:42:57 +01:00
.numElements = vertexIndices.size(),
2023-11-05 10:36:01 +01:00
.dynamic = true,
2023-11-15 17:42:57 +01:00
});
2023-11-10 19:18:09 +01:00
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
2023-11-01 23:12:30 +01:00
.sourceData = {
2023-10-31 23:44:46 +01:00
.size = sizeof(uint8) * primitiveIndices.size(),
.data = (uint8*)primitiveIndices.data(),
},
2023-11-15 17:42:57 +01:00
.numElements = primitiveIndices.size(),
2023-11-05 10:36:01 +01:00
.dynamic = true,
2023-11-15 17:42:57 +01:00
});
2023-10-24 15:01:09 +02:00
}
2023-10-31 17:55:30 +01:00
MeshId VertexData::allocateVertexData(uint64 numVertices)
{
MeshId res{ idCounter++ };
meshOffsets[res] = head;
2023-11-09 22:15:51 +01:00
meshVertexCounts[res] = numVertices;
2023-10-31 17:55:30 +01:00
head += numVertices;
if (head > verticesAllocated)
{
verticesAllocated = head;
resizeBuffers();
}
return res;
}
2023-11-09 22:15:51 +01:00
uint64 VertexData::getMeshOffset(MeshId id)
{
return meshOffsets[id];
}
2023-11-09 22:15:51 +01:00
uint64 VertexData::getMeshVertexCount(MeshId id)
{
return meshVertexCounts[id];
}
2023-10-24 15:01:09 +02:00
List<VertexData*> vertexDataList;
List<VertexData*> VertexData::getList()
{
return vertexDataList;
}
2023-11-01 13:38:49 +01:00
VertexData* Seele::VertexData::findByTypeName(std::string name)
{
for (auto vd : vertexDataList)
{
if (vd->getTypeName() == name)
{
return vd;
}
}
return nullptr;
}
2023-10-31 16:16:23 +01:00
void Seele::VertexData::init(Gfx::PGraphics graphics)
2023-10-24 15:01:09 +02:00
{
2023-10-31 16:16:23 +01:00
this->graphics = graphics;
2023-10-31 17:55:30 +01:00
verticesAllocated = NUM_DEFAULT_ELEMENTS;
2023-10-24 15:01:09 +02:00
instanceDataLayout = graphics->createDescriptorLayout("VertexDataInstanceLayout");
instanceDataLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2023-11-07 16:55:13 +01:00
if (graphics->supportMeshShading())
2023-10-24 15:01:09 +02:00
{
// meshData
instanceDataLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
// meshletData
instanceDataLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2023-10-31 23:44:46 +01:00
// primitiveIndices
instanceDataLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
// vetexIndices
instanceDataLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2023-10-24 15:01:09 +02:00
}
instanceDataLayout->create();
2023-10-31 17:55:30 +01:00
resizeBuffers();
2023-11-05 10:36:01 +01:00
graphics->getShaderCompiler()->registerVertexData(this);
2023-10-29 09:20:23 +01:00
}
2023-10-31 16:16:23 +01:00
VertexData::VertexData()
: idCounter(0)
2023-11-05 10:36:01 +01:00
, head(0)
, verticesAllocated(0)
2023-11-06 14:47:21 +01:00
, dirty(false)
2023-10-31 16:16:23 +01:00
{
}
2023-11-01 13:38:49 +01:00
2023-11-05 10:36:01 +01:00
void Meshlet::save(ArchiveBuffer& buffer) const
2023-11-01 13:38:49 +01:00
{
Serialization::save(buffer, uniqueVertices);
Serialization::save(buffer, primitiveLayout);
Serialization::save(buffer, numVertices);
Serialization::save(buffer, numPrimitives);
}
void Meshlet::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, uniqueVertices);
Serialization::load(buffer, primitiveLayout);
Serialization::load(buffer, numVertices);
Serialization::load(buffer, numPrimitives);
}