2023-10-24 15:01:09 +02:00
|
|
|
#include "VertexData.h"
|
2023-10-26 18:37:29 +02:00
|
|
|
#include "Graphics/Descriptor.h"
|
2024-06-09 12:20:04 +02:00
|
|
|
#include "Graphics/Enums.h"
|
|
|
|
|
#include "Graphics/Graphics.h"
|
|
|
|
|
#include "Graphics/Initializer.h"
|
2024-01-24 23:10:33 +01:00
|
|
|
#include "Graphics/Mesh.h"
|
2024-06-09 12:20:04 +02:00
|
|
|
#include "Graphics/Shader.h"
|
|
|
|
|
#include "Material/Material.h"
|
2024-06-09 10:44:24 +02:00
|
|
|
#include "Material/MaterialInstance.h"
|
2024-08-08 22:14:25 +02:00
|
|
|
#include <iostream>
|
2023-10-24 15:01:09 +02:00
|
|
|
|
|
|
|
|
using namespace Seele;
|
|
|
|
|
|
2024-10-07 20:14:00 +02:00
|
|
|
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 36;
|
2024-06-07 09:19:47 +02:00
|
|
|
uint64 VertexData::meshletCount = 0;
|
2023-10-31 17:55:30 +01:00
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void VertexData::resetMeshData() {
|
2024-06-07 09:19:47 +02:00
|
|
|
std::unique_lock l(materialDataLock);
|
2025-04-11 18:15:39 +02:00
|
|
|
instanceData.clear(true);
|
|
|
|
|
instanceMeshData.clear(true);
|
|
|
|
|
rayTracingScene.clear(true);
|
|
|
|
|
transparentData.clear(true);
|
2024-06-09 12:20:04 +02:00
|
|
|
for (auto& mat : materialData) {
|
|
|
|
|
for (auto& inst : mat.instances) {
|
2025-04-11 18:15:39 +02:00
|
|
|
inst.instanceData.clear(true);
|
|
|
|
|
inst.instanceMeshData.clear(true);
|
|
|
|
|
inst.cullingOffsets.clear(true);
|
|
|
|
|
inst.rayTracingData.clear(true);
|
2024-06-07 09:19:47 +02:00
|
|
|
}
|
2024-06-09 12:20:04 +02:00
|
|
|
if (mat.material != nullptr) {
|
2024-06-07 09:19:47 +02:00
|
|
|
mat.material->getDescriptorLayout()->reset();
|
|
|
|
|
}
|
2023-11-17 18:46:37 +01:00
|
|
|
}
|
2024-06-09 12:20:04 +02:00
|
|
|
if (dirty) {
|
2024-06-07 09:19:47 +02:00
|
|
|
updateBuffers();
|
|
|
|
|
dirty = false;
|
2023-10-31 16:16:23 +01:00
|
|
|
}
|
2023-10-24 15:01:09 +02:00
|
|
|
}
|
|
|
|
|
|
2024-09-07 11:15:47 +02:00
|
|
|
void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transform& transform) {
|
2024-06-07 09:19:47 +02:00
|
|
|
std::unique_lock l(materialDataLock);
|
|
|
|
|
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
|
|
|
|
PMaterial mat = referencedInstance->getBaseMaterial();
|
2024-06-20 21:57:26 +02:00
|
|
|
Matrix4 transformMatrix = transform.toMatrix() * mesh->transform;
|
|
|
|
|
InstanceData inst = InstanceData{
|
|
|
|
|
.transformMatrix = transformMatrix,
|
|
|
|
|
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
|
|
|
|
};
|
|
|
|
|
|
2024-07-17 09:33:37 +02:00
|
|
|
referencedInstance->updateDescriptor();
|
2024-06-09 12:20:04 +02:00
|
|
|
if (materialData.size() <= mat->getId()) {
|
2024-06-07 09:19:47 +02:00
|
|
|
materialData.resize(mat->getId() + 1);
|
|
|
|
|
}
|
2024-06-09 12:20:04 +02:00
|
|
|
MaterialData& matData = materialData[mat->getId()];
|
2024-06-07 09:19:47 +02:00
|
|
|
matData.material = mat;
|
2024-06-09 12:20:04 +02:00
|
|
|
if (matData.instances.size() <= referencedInstance->getId()) {
|
2024-06-07 09:19:47 +02:00
|
|
|
matData.instances.resize(referencedInstance->getId() + 1);
|
|
|
|
|
}
|
2024-06-09 12:20:04 +02:00
|
|
|
BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()];
|
2025-03-10 18:35:35 +01:00
|
|
|
matInstanceData.materialInstance = referencedInstance;
|
2025-04-14 22:26:33 +02:00
|
|
|
for (const auto& data : registeredMeshes[mesh->id].meshData) {
|
2025-03-09 22:42:05 +01:00
|
|
|
if (mat->hasTransparency()) {
|
|
|
|
|
auto params = referencedInstance->getMaterialOffsets();
|
|
|
|
|
transparentData.add(TransparentDraw{
|
|
|
|
|
.matInst = referencedInstance,
|
|
|
|
|
.vertexData = this,
|
|
|
|
|
.offsets =
|
|
|
|
|
{
|
|
|
|
|
.instanceOffset = 0,
|
|
|
|
|
.textureOffset = params.textureOffset,
|
|
|
|
|
.samplerOffset = params.samplerOffset,
|
|
|
|
|
.floatOffset = params.floatOffset,
|
|
|
|
|
},
|
|
|
|
|
.worldPosition = Vector(inst.transformMatrix[3]),
|
|
|
|
|
.instanceData = inst,
|
|
|
|
|
.meshData = data,
|
|
|
|
|
.cullingOffset = meshletOffset,
|
|
|
|
|
.rayTracingScene = mesh->blas,
|
|
|
|
|
});
|
|
|
|
|
} else { // opaque
|
|
|
|
|
matInstanceData.rayTracingData.add(mesh->blas);
|
|
|
|
|
matInstanceData.instanceData.add(inst);
|
|
|
|
|
matInstanceData.instanceMeshData.add(data);
|
|
|
|
|
matInstanceData.cullingOffsets.add(meshletOffset);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-24 15:01:09 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void VertexData::createDescriptors() {
|
2024-06-07 09:19:47 +02:00
|
|
|
std::unique_lock l(materialDataLock);
|
2024-05-12 19:36:32 +02:00
|
|
|
|
2024-06-07 09:19:47 +02:00
|
|
|
Array<uint32> cullingOffsets;
|
2024-06-09 12:20:04 +02:00
|
|
|
for (auto& mat : materialData) {
|
|
|
|
|
for (auto& instance : mat.instances) {
|
2025-03-20 20:15:38 +01:00
|
|
|
instance.offsets.instanceOffset = (uint32)instanceData.size();
|
2024-06-18 19:19:05 +02:00
|
|
|
MaterialOffsets offsets = instance.materialInstance->getMaterialOffsets();
|
|
|
|
|
instance.offsets.textureOffset = offsets.textureOffset;
|
|
|
|
|
instance.offsets.samplerOffset = offsets.samplerOffset;
|
|
|
|
|
instance.offsets.floatOffset = offsets.floatOffset;
|
2024-06-09 12:20:04 +02:00
|
|
|
for (size_t i = 0; i < instance.instanceData.size(); ++i) {
|
2024-06-07 09:19:47 +02:00
|
|
|
cullingOffsets.add(instance.cullingOffsets[i]);
|
|
|
|
|
instanceData.add(instance.instanceData[i]);
|
|
|
|
|
instanceMeshData.add(instance.instanceMeshData[i]);
|
2024-07-10 21:07:10 +02:00
|
|
|
rayTracingScene.add(instance.rayTracingData[i]);
|
2024-06-07 09:19:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
2024-05-12 19:36:32 +02:00
|
|
|
}
|
2024-07-18 11:45:56 +02:00
|
|
|
for (uint32 i = 0; i < transparentData.size(); ++i) {
|
2025-03-20 20:15:38 +01:00
|
|
|
transparentData[i].offsets.instanceOffset = (uint32)instanceData.size();
|
2024-07-19 10:42:59 +02:00
|
|
|
cullingOffsets.add(transparentData[i].cullingOffset);
|
2024-07-17 10:40:40 +02:00
|
|
|
instanceData.add(transparentData[i].instanceData);
|
|
|
|
|
instanceMeshData.add(transparentData[i].meshData);
|
|
|
|
|
rayTracingScene.add(transparentData[i].rayTracingScene);
|
|
|
|
|
}
|
2024-06-07 09:19:47 +02:00
|
|
|
cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
2024-08-08 22:14:25 +02:00
|
|
|
cullingOffsetBuffer->updateContents(0, cullingOffsets.size() * sizeof(uint32), cullingOffsets.data());
|
2024-06-09 12:20:04 +02:00
|
|
|
cullingOffsetBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
|
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
2024-05-08 10:51:59 +02:00
|
|
|
|
2024-06-07 09:19:47 +02:00
|
|
|
instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData));
|
2024-08-08 22:14:25 +02:00
|
|
|
instanceBuffer->updateContents(0, instanceData.size() * sizeof(InstanceData), instanceData.data());
|
2024-06-09 12:20:04 +02:00
|
|
|
instanceBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
|
|
|
|
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
2024-05-30 21:24:21 +02:00
|
|
|
|
2024-06-07 09:19:47 +02:00
|
|
|
instanceMeshDataBuffer->rotateBuffer(sizeof(MeshData) * instanceMeshData.size());
|
2024-08-08 22:14:25 +02:00
|
|
|
instanceMeshDataBuffer->updateContents(0, sizeof(MeshData) * instanceMeshData.size(), instanceMeshData.data());
|
2024-06-09 12:20:04 +02:00
|
|
|
instanceMeshDataBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
|
|
|
|
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
2024-06-20 21:57:26 +02:00
|
|
|
|
2024-06-07 09:19:47 +02:00
|
|
|
instanceDataLayout->reset();
|
|
|
|
|
descriptorSet = instanceDataLayout->allocateDescriptorSet();
|
2025-02-28 16:56:51 +09:00
|
|
|
descriptorSet->updateBuffer(INSTANCES_NAME, 0, instanceBuffer);
|
|
|
|
|
descriptorSet->updateBuffer(MESHDATA_NAME, 0, instanceMeshDataBuffer);
|
|
|
|
|
descriptorSet->updateBuffer(MESHLET_NAME, 0, meshletBuffer);
|
|
|
|
|
descriptorSet->updateBuffer(PRIMITIVEINDICES_NAME, 0, primitiveIndicesBuffer);
|
|
|
|
|
descriptorSet->updateBuffer(VERTEXINDICES_NAME, 0, vertexIndicesBuffer);
|
|
|
|
|
descriptorSet->updateBuffer(CULLINGOFFSETS_NAME, 0, cullingOffsetBuffer);
|
2024-06-18 19:19:05 +02:00
|
|
|
Material::updateDescriptor();
|
2023-11-10 19:18:09 +01:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
|
2024-07-05 12:02:46 +02:00
|
|
|
std::unique_lock l(vertexDataLock);
|
2025-04-14 22:26:33 +02:00
|
|
|
RegisteredMesh& mesh = registeredMeshes[id];
|
2025-04-15 13:29:12 +02:00
|
|
|
assert(mesh.meshData.empty()); // TODO: update if not empty
|
2025-04-12 17:40:14 +02:00
|
|
|
uint32 numChunks = (loadedMeshlets.size() + 2047) / 2048;
|
2025-04-14 16:03:16 +02:00
|
|
|
for (uint32 chunkIdx = 0; chunkIdx < numChunks; ++chunkIdx) {
|
2025-04-12 17:40:14 +02:00
|
|
|
uint32 chunkOffset = chunkIdx * 2048;
|
|
|
|
|
uint32 numRemaining = loadedMeshlets.size() - chunkOffset;
|
2025-04-15 13:29:12 +02:00
|
|
|
|
|
|
|
|
AABB meshAABB;
|
|
|
|
|
uint32 meshletOffset = meshlets.size();
|
2025-04-12 17:40:14 +02:00
|
|
|
for (uint32 chunk = 0; chunk < std::min(numRemaining, 2048u); chunk++) {
|
|
|
|
|
Meshlet& m = loadedMeshlets[chunkOffset + chunk];
|
2025-03-09 22:42:05 +01:00
|
|
|
//...
|
|
|
|
|
meshAABB = meshAABB.combine(m.boundingBox);
|
2025-04-15 13:29:12 +02:00
|
|
|
|
2025-03-20 20:15:38 +01:00
|
|
|
uint32 vertexOffset = (uint32)vertexIndices.size();
|
2025-03-09 22:42:05 +01:00
|
|
|
vertexIndices.resize(vertexOffset + m.numVertices);
|
|
|
|
|
std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32));
|
2025-04-15 13:29:12 +02:00
|
|
|
|
2025-03-20 20:15:38 +01:00
|
|
|
uint32 primitiveOffset = (uint32)primitiveIndices.size();
|
2025-03-09 22:42:05 +01:00
|
|
|
primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3));
|
|
|
|
|
std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8));
|
2025-04-15 13:29:12 +02:00
|
|
|
|
2025-03-09 22:42:05 +01:00
|
|
|
meshlets.add(MeshletDescription{
|
|
|
|
|
.bounding = m.boundingBox, //.toSphere(),
|
2025-04-14 22:26:33 +02:00
|
|
|
.vertexIndices =
|
|
|
|
|
{
|
|
|
|
|
.offset = vertexOffset,
|
|
|
|
|
.size = m.numVertices,
|
|
|
|
|
},
|
|
|
|
|
.primitiveIndices =
|
|
|
|
|
{
|
|
|
|
|
.offset = primitiveOffset,
|
|
|
|
|
.size = m.numPrimitives,
|
|
|
|
|
},
|
2025-03-09 22:42:05 +01:00
|
|
|
.color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX),
|
2025-04-15 13:29:12 +02:00
|
|
|
.indicesOffset = (uint32)registeredMeshes[id].vertexOffset,
|
2025-03-09 22:42:05 +01:00
|
|
|
});
|
|
|
|
|
}
|
2025-04-14 22:26:33 +02:00
|
|
|
registeredMeshes[id].meshData.add(MeshData{
|
2025-03-09 22:42:05 +01:00
|
|
|
.bounding = meshAABB, //.toSphere(),
|
2025-04-14 22:26:33 +02:00
|
|
|
.meshletRange =
|
|
|
|
|
{
|
|
|
|
|
.offset = meshletOffset,
|
2025-04-15 13:29:12 +02:00
|
|
|
.size = std::min(numRemaining, 2048u),
|
2025-04-14 22:26:33 +02:00
|
|
|
},
|
2024-07-05 12:02:46 +02:00
|
|
|
});
|
|
|
|
|
}
|
2025-03-09 22:42:05 +01:00
|
|
|
// todo: in case of a index split for 16 bit, do something here
|
2025-04-14 22:26:33 +02:00
|
|
|
registeredMeshes[id].meshData[0].indicesRange = {
|
|
|
|
|
.offset = (uint32)indices.size(),
|
|
|
|
|
.size = (uint32)loadedIndices.size(),
|
|
|
|
|
};
|
2024-07-05 12:02:46 +02:00
|
|
|
indices.resize(indices.size() + loadedIndices.size());
|
2025-04-15 13:29:12 +02:00
|
|
|
std::memcpy(indices.data() + registeredMeshes[id].meshData[0].indicesRange.offset, loadedIndices.data(),
|
|
|
|
|
loadedIndices.size() * sizeof(uint32));
|
2024-06-20 21:57:26 +02:00
|
|
|
}
|
|
|
|
|
|
2025-04-15 13:29:12 +02:00
|
|
|
void VertexData::removeMesh(MeshId id) {
|
|
|
|
|
RegisteredMesh& removing = registeredMeshes[id];
|
|
|
|
|
uint32 meshletOffset = meshlets.size();
|
2025-04-14 16:03:16 +02:00
|
|
|
uint32 numMeshlets = 0;
|
2025-04-15 13:29:12 +02:00
|
|
|
uint32 vertexIndicesOffset = vertexIndices.size();
|
|
|
|
|
uint32 numVertexIndices = 0;
|
|
|
|
|
uint32 primitiveIndicesOffset = primitiveIndices.size();
|
|
|
|
|
uint32 numPrimitiveIndices = 0;
|
2025-04-17 20:58:12 +02:00
|
|
|
uint32 indicesOffset = removing.meshData[0].indicesRange.offset;
|
|
|
|
|
uint32 numIndices = removing.meshData[0].indicesRange.size;
|
2025-04-15 13:29:12 +02:00
|
|
|
for (const auto& data : removing.meshData) {
|
|
|
|
|
meshletOffset = std::min(meshletOffset, data.meshletRange.offset);
|
|
|
|
|
numMeshlets += data.meshletRange.size;
|
2025-04-17 20:58:12 +02:00
|
|
|
for (uint32 m = 0; m < data.meshletRange.size; ++m) {
|
|
|
|
|
MeshletDescription& meshlet = meshlets[data.meshletRange.offset + m];
|
2025-04-15 13:29:12 +02:00
|
|
|
vertexIndicesOffset = std::min(vertexIndicesOffset, meshlet.vertexIndices.offset);
|
|
|
|
|
numVertexIndices += meshlet.vertexIndices.size;
|
|
|
|
|
primitiveIndicesOffset = std::min(primitiveIndicesOffset, meshlet.primitiveIndices.offset);
|
|
|
|
|
numPrimitiveIndices += meshlet.primitiveIndices.size;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (auto& mesh : registeredMeshes) {
|
|
|
|
|
for (auto& data : mesh.meshData) {
|
|
|
|
|
if (data.meshletRange.offset > meshletOffset) {
|
|
|
|
|
for (uint32 i = 0; i < data.meshletRange.size; ++i) {
|
2025-04-17 20:58:12 +02:00
|
|
|
MeshletDescription& m = meshlets[data.meshletRange.offset + i];
|
2025-04-15 13:29:12 +02:00
|
|
|
if (m.primitiveIndices.offset > primitiveIndicesOffset) {
|
|
|
|
|
m.primitiveIndices.offset -= numPrimitiveIndices;
|
|
|
|
|
}
|
|
|
|
|
if (m.vertexIndices.offset > vertexIndicesOffset) {
|
|
|
|
|
m.vertexIndices.offset -= numVertexIndices;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data.meshletRange.offset -= numMeshlets;
|
2025-04-17 20:58:12 +02:00
|
|
|
data.indicesRange.offset -= numIndices;
|
2025-04-15 13:29:12 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
uint32 numMeshletsToMove = meshlets.size() - (meshletOffset + numMeshlets);
|
|
|
|
|
uint32 numVertexIndicesToMove = vertexIndices.size() - (vertexIndicesOffset + numVertexIndices);
|
|
|
|
|
uint32 numPrimitiveIndicesToMove = primitiveIndices.size() - (primitiveIndicesOffset + numPrimitiveIndices);
|
|
|
|
|
std::move(meshlets.begin() + meshletOffset + numMeshlets, meshlets.begin() + meshletOffset + numMeshlets + numMeshletsToMove,
|
|
|
|
|
meshlets.begin() + meshletOffset);
|
|
|
|
|
std::move(vertexIndices.begin() + vertexIndicesOffset + numVertexIndices,
|
|
|
|
|
vertexIndices.begin() + vertexIndicesOffset + numVertexIndices + numVertexIndicesToMove,
|
|
|
|
|
vertexIndices.begin() + vertexIndicesOffset);
|
|
|
|
|
std::move(primitiveIndices.begin() + primitiveIndicesOffset + numPrimitiveIndices,
|
2025-04-17 20:58:12 +02:00
|
|
|
primitiveIndices.begin() + primitiveIndicesOffset + numPrimitiveIndices + numPrimitiveIndicesToMove,
|
2025-04-15 13:29:12 +02:00
|
|
|
primitiveIndices.begin() + primitiveIndicesOffset);
|
2025-04-17 20:58:12 +02:00
|
|
|
uint32 numIndicesToMove = indices.size() - (indicesOffset + numIndices);
|
|
|
|
|
std::move(indices.begin() + indicesOffset + numIndices, indices.begin() + indicesOffset + numIndices + numIndicesToMove,
|
|
|
|
|
indices.begin() + indicesOffset);
|
2025-04-14 16:03:16 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-20 21:57:26 +02:00
|
|
|
void VertexData::commitMeshes() {
|
2024-07-05 12:02:46 +02:00
|
|
|
indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
|
|
|
|
|
.sourceData =
|
|
|
|
|
{
|
|
|
|
|
.size = sizeof(uint32) * indices.size(),
|
|
|
|
|
.data = (uint8*)indices.data(),
|
|
|
|
|
},
|
|
|
|
|
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
|
|
|
|
|
.name = "IndexBuffer",
|
|
|
|
|
});
|
|
|
|
|
meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
|
|
|
.sourceData =
|
|
|
|
|
{
|
|
|
|
|
.size = sizeof(MeshletDescription) * meshlets.size(),
|
|
|
|
|
.data = (uint8*)meshlets.data(),
|
|
|
|
|
},
|
|
|
|
|
.numElements = meshlets.size(),
|
|
|
|
|
.name = "MeshletBuffer",
|
|
|
|
|
});
|
|
|
|
|
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
|
|
|
.sourceData =
|
|
|
|
|
{
|
|
|
|
|
.size = sizeof(uint32) * vertexIndices.size(),
|
|
|
|
|
.data = (uint8*)vertexIndices.data(),
|
|
|
|
|
},
|
|
|
|
|
.numElements = vertexIndices.size(),
|
|
|
|
|
.name = "VertexIndicesBuffer",
|
|
|
|
|
});
|
2024-05-18 21:23:59 +02:00
|
|
|
|
2024-07-05 12:02:46 +02:00
|
|
|
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
|
|
|
.sourceData =
|
|
|
|
|
{
|
|
|
|
|
.size = sizeof(uint8) * primitiveIndices.size(),
|
|
|
|
|
.data = (uint8*)primitiveIndices.data(),
|
|
|
|
|
},
|
|
|
|
|
.numElements = primitiveIndices.size(),
|
|
|
|
|
.name = "PrimitiveIndicesBuffer",
|
|
|
|
|
});
|
2024-07-15 08:32:50 +02:00
|
|
|
updateBuffers();
|
|
|
|
|
dirty = false;
|
2024-12-25 14:59:08 +01:00
|
|
|
graphics->buildBottomLevelAccelerationStructures(std::move(dataToBuild));
|
2023-10-24 15:01:09 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
MeshId VertexData::allocateVertexData(uint64 numVertices) {
|
2024-07-05 12:02:46 +02:00
|
|
|
std::unique_lock l(vertexDataLock);
|
|
|
|
|
MeshId res{idCounter++};
|
2025-04-14 22:26:33 +02:00
|
|
|
registeredMeshes.add({
|
|
|
|
|
.vertexOffset = head,
|
|
|
|
|
.vertexCount = numVertices,
|
|
|
|
|
});
|
2024-07-05 12:02:46 +02:00
|
|
|
head += numVertices;
|
|
|
|
|
if (head > verticesAllocated) {
|
2024-08-08 22:14:25 +02:00
|
|
|
verticesAllocated = 2 * head; // double capacity
|
|
|
|
|
std::cout << "Resizing buffers to " << verticesAllocated << std::endl;
|
2024-07-05 12:02:46 +02:00
|
|
|
resizeBuffers();
|
|
|
|
|
}
|
|
|
|
|
return res;
|
2023-10-31 17:55:30 +01:00
|
|
|
}
|
|
|
|
|
|
2025-03-09 22:42:05 +01:00
|
|
|
void VertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
2024-07-18 11:45:56 +02:00
|
|
|
std::unique_lock l(vertexDataLock);
|
|
|
|
|
Array<Meshlet> out;
|
2025-04-14 22:26:33 +02:00
|
|
|
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];
|
2025-03-09 22:42:05 +01:00
|
|
|
Meshlet m;
|
2025-04-14 22:26:33 +02:00
|
|
|
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;
|
2025-03-09 22:42:05 +01:00
|
|
|
m.boundingBox = desc.bounding;
|
|
|
|
|
out.add(std::move(m));
|
|
|
|
|
}
|
2024-07-18 11:45:56 +02:00
|
|
|
}
|
2025-04-14 22:26:33 +02:00
|
|
|
Array<uint32> ind(registeredMeshes[id].meshData[0].indicesRange.size);
|
2025-04-15 13:29:12 +02:00
|
|
|
std::memcpy(ind.data(), &indices[registeredMeshes[id].meshData[0].indicesRange.offset],
|
|
|
|
|
registeredMeshes[id].meshData[0].indicesRange.size * sizeof(uint32));
|
2024-07-18 11:45:56 +02:00
|
|
|
Serialization::save(buffer, out);
|
|
|
|
|
Serialization::save(buffer, ind);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-07 11:15:47 +02:00
|
|
|
uint64 VertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
2024-07-18 11:45:56 +02:00
|
|
|
Array<Meshlet> in;
|
|
|
|
|
Array<uint32> ind;
|
|
|
|
|
Serialization::load(buffer, in);
|
|
|
|
|
Serialization::load(buffer, ind);
|
|
|
|
|
loadMesh(id, ind, in);
|
2024-08-07 21:19:33 +02:00
|
|
|
uint64 result = in.size() * sizeof(MeshletDescription);
|
|
|
|
|
result += ind.size() * sizeof(uint32);
|
|
|
|
|
return result;
|
2024-07-18 11:45:56 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
List<VertexData*> vertexDataList;
|
2023-10-24 15:01:09 +02:00
|
|
|
|
2025-04-08 23:18:50 +02:00
|
|
|
void VertexData::addVertexDataInstance(VertexData* vertexData) { vertexDataList.add(vertexData); }
|
|
|
|
|
|
2024-07-05 12:02:46 +02:00
|
|
|
List<VertexData*> VertexData::getList() { return vertexDataList; }
|
2023-10-24 15:01:09 +02:00
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
VertexData* VertexData::findByTypeName(std::string name) {
|
2024-07-05 12:02:46 +02:00
|
|
|
for (auto vd : vertexDataList) {
|
|
|
|
|
if (vd->getTypeName() == name) {
|
|
|
|
|
return vd;
|
2024-06-07 09:19:47 +02:00
|
|
|
}
|
2024-07-05 12:02:46 +02:00
|
|
|
}
|
|
|
|
|
return nullptr;
|
2023-11-01 13:38:49 +01:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void VertexData::init(Gfx::PGraphics _graphics) {
|
2024-07-05 12:02:46 +02:00
|
|
|
graphics = _graphics;
|
|
|
|
|
verticesAllocated = NUM_DEFAULT_ELEMENTS;
|
|
|
|
|
instanceDataLayout = graphics->createDescriptorLayout("pScene");
|
2023-11-26 09:40:48 +01:00
|
|
|
|
2024-07-05 12:02:46 +02:00
|
|
|
// instanceData
|
|
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
2025-02-28 16:56:51 +09:00
|
|
|
.name = INSTANCES_NAME,
|
2024-07-05 12:02:46 +02:00
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
|
|
|
|
// meshData
|
|
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
2025-02-28 16:56:51 +09:00
|
|
|
.name = MESHDATA_NAME,
|
2024-07-05 12:02:46 +02:00
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
|
|
|
|
// meshletData
|
2025-02-28 16:56:51 +09:00
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
|
|
|
.name = MESHLET_NAME,
|
|
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
2024-07-05 12:02:46 +02:00
|
|
|
// primitiveIndices
|
2025-02-28 16:56:51 +09:00
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
|
|
|
.name = PRIMITIVEINDICES_NAME,
|
|
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
2024-07-05 12:02:46 +02:00
|
|
|
// vertexIndices
|
2025-02-28 16:56:51 +09:00
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
|
|
|
.name = VERTEXINDICES_NAME,
|
|
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
2024-07-05 12:02:46 +02:00
|
|
|
// cullingOffset
|
2025-02-28 16:56:51 +09:00
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
|
|
|
.name = CULLINGOFFSETS_NAME,
|
|
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
2024-07-05 12:02:46 +02:00
|
|
|
// cullingInfos
|
2025-02-28 16:56:51 +09:00
|
|
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
|
|
|
|
.name = CULLINGDATA_NAME,
|
|
|
|
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
|
|
|
|
});
|
2024-05-18 21:23:59 +02:00
|
|
|
|
2024-07-05 12:02:46 +02:00
|
|
|
instanceDataLayout->create();
|
2024-06-07 09:19:47 +02:00
|
|
|
|
2024-07-05 12:02:46 +02:00
|
|
|
cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
|
|
|
.name = "MeshletOffset",
|
|
|
|
|
});
|
|
|
|
|
instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
|
|
|
.name = "InstanceBuffer",
|
|
|
|
|
});
|
|
|
|
|
instanceMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
|
|
|
.name = "MeshDataBuffer",
|
|
|
|
|
});
|
2024-08-08 22:53:49 +02:00
|
|
|
resizeBuffers();
|
2024-07-05 12:02:46 +02:00
|
|
|
graphics->getShaderCompiler()->registerVertexData(this);
|
2023-10-29 09:20:23 +01:00
|
|
|
}
|
2023-10-31 16:16:23 +01:00
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
void VertexData::destroy() {
|
2024-07-18 11:45:56 +02:00
|
|
|
cullingOffsetBuffer = nullptr;
|
2024-07-05 12:02:46 +02:00
|
|
|
instanceBuffer = nullptr;
|
|
|
|
|
instanceMeshDataBuffer = nullptr;
|
|
|
|
|
instanceDataLayout = nullptr;
|
|
|
|
|
meshletBuffer = nullptr;
|
|
|
|
|
vertexIndicesBuffer = nullptr;
|
|
|
|
|
primitiveIndicesBuffer = nullptr;
|
|
|
|
|
indexBuffer = nullptr;
|
2025-04-14 22:26:33 +02:00
|
|
|
registeredMeshes.clear();
|
2024-07-05 12:02:46 +02:00
|
|
|
materialData.clear();
|
2024-06-07 09:19:47 +02:00
|
|
|
}
|
|
|
|
|
|
2024-09-07 11:15:47 +02:00
|
|
|
uint32 VertexData::addCullingMapping(MeshId id) {
|
2025-03-20 20:15:38 +01:00
|
|
|
uint32 result = (uint32)meshletCount;
|
2025-03-09 22:42:05 +01:00
|
|
|
for (const auto& md : getMeshData(id)) {
|
2025-04-14 22:26:33 +02:00
|
|
|
meshletCount += md.meshletRange.size;
|
2025-03-09 22:42:05 +01:00
|
|
|
}
|
2024-09-07 11:15:47 +02:00
|
|
|
return result;
|
2023-12-12 11:37:00 +01:00
|
|
|
}
|
|
|
|
|
|
2024-06-09 12:20:04 +02:00
|
|
|
VertexData::VertexData() : idCounter(0), head(0), verticesAllocated(0), dirty(false) {}
|