implement global index buffer

This commit is contained in:
Dynamitos
2023-11-26 11:27:39 +01:00
parent 89cee2e41a
commit 52c7fce931
9 changed files with 58 additions and 81 deletions
+1 -2
View File
@@ -18,7 +18,7 @@ struct MeshData
static const uint MAX_VERTICES = 64; static const uint MAX_VERTICES = 64;
static const uint MAX_PRIMITIVES = 126; static const uint MAX_PRIMITIVES = 126;
static const uint TASK_GROUP_SIZE = 1; static const uint TASK_GROUP_SIZE = 128;
static const uint MESH_GROUP_SIZE = 32; static const uint MESH_GROUP_SIZE = 32;
static const uint MAX_MESHLETS_PER_MESH = 512; static const uint MAX_MESHLETS_PER_MESH = 512;
@@ -33,7 +33,6 @@ struct Scene
StructuredBuffer<MeshData> meshData; StructuredBuffer<MeshData> meshData;
StructuredBuffer<MeshletDescription> meshletInfos; StructuredBuffer<MeshletDescription> meshletInfos;
StructuredBuffer<uint8_t> primitiveIndices; StructuredBuffer<uint8_t> primitiveIndices;
StructuredBuffer<uint32_t> vertexIndices; StructuredBuffer<uint32_t> vertexIndices;
}; };
+1 -10
View File
@@ -195,18 +195,10 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
Array<Meshlet> meshlets; Array<Meshlet> meshlets;
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet)); meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
Meshlet::buildFromIndexBuffer(indices, meshlets); Meshlet::buildFromIndexBuffer(indices, meshlets);
vertexData->loadMesh(id, meshlets); vertexData->loadMesh(id, indices, meshlets);
collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f)); collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
IndexBufferCreateInfo idxInfo;
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
idxInfo.sourceData.data = (uint8*)indices.data();
idxInfo.sourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
idxInfo.sourceData.size = sizeof(uint32) * indices.size();
Gfx::OIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo);
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
globalMeshes[meshIndex] = new Mesh(); globalMeshes[meshIndex] = new Mesh();
globalMeshes[meshIndex]->vertexData = vertexData; globalMeshes[meshIndex]->vertexData = vertexData;
globalMeshes[meshIndex]->id = id; globalMeshes[meshIndex]->id = id;
@@ -214,7 +206,6 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
globalMeshes[meshIndex]->meshlets = std::move(meshlets); globalMeshes[meshIndex]->meshlets = std::move(meshlets);
globalMeshes[meshIndex]->indices = std::move(indices); globalMeshes[meshIndex]->indices = std::move(indices);
globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices; globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices;
globalMeshes[meshIndex]->indexBuffer = std::move(indexBuffer);
} }
} }
+1 -8
View File
@@ -29,18 +29,11 @@ void Mesh::load(ArchiveBuffer& buffer)
Serialization::load(buffer, vertexCount); Serialization::load(buffer, vertexCount);
vertexData = VertexData::findByTypeName(typeName); vertexData = VertexData::findByTypeName(typeName);
Serialization::load(buffer, indices); Serialization::load(buffer, indices);
indexBuffer = buffer.getGraphics()->createIndexBuffer(IndexBufferCreateInfo{
.sourceData = {
.size = sizeof(uint32) * indices.size(),
.data = (uint8*)indices.data(),
},
.indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT32,
});
Serialization::load(buffer, meshlets); Serialization::load(buffer, meshlets);
std::string refId; std::string refId;
Serialization::load(buffer, refId); Serialization::load(buffer, refId);
referencedMaterial = AssetRegistry::findMaterialInstance(refId); referencedMaterial = AssetRegistry::findMaterialInstance(refId);
id = vertexData->allocateVertexData(vertexCount); id = vertexData->allocateVertexData(vertexCount);
vertexData->loadMesh(id, meshlets); vertexData->loadMesh(id, indices, meshlets);
vertexData->deserializeMesh(id, buffer); vertexData->deserializeMesh(id, buffer);
} }
-1
View File
@@ -14,7 +14,6 @@ public:
VertexData* vertexData; VertexData* vertexData;
MeshId id; MeshId id;
uint64 vertexCount; uint64 vertexCount;
Gfx::OIndexBuffer indexBuffer;
PMaterialInstanceAsset referencedMaterial; PMaterialInstanceAsset referencedMaterial;
Array<uint32> indices; Array<uint32> indices;
Array<Meshlet> meshlets; Array<Meshlet> meshlets;
+5 -11
View File
@@ -155,24 +155,18 @@ void BasePass::render()
command->bindDescriptor(descriptorSets); command->bindDescriptor(descriptorSets);
if (graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
command->dispatch(instance.numMeshes, 1, 1); command->dispatch(instance.meshes.size(), 1, 1);
} }
else else
{ {
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0; uint32 instanceOffset = 0;
for (const auto& mesh : instance.meshes) for (const auto& [instance, meshData] : instance.meshes)
{ {
uint32 vertexOffset = vertexData->getMeshOffset(mesh.id); if (meshData.numIndices > 0)
if (mesh.indexBuffer != nullptr)
{ {
command->bindIndexBuffer(mesh.indexBuffer); command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset++);
command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset);
} }
else
{
command->draw(vertexData->getMeshVertexCount(mesh.id), 1, vertexOffset, instanceOffset);
}
instanceOffset += mesh.meshes;
} }
} }
} }
@@ -112,26 +112,20 @@ void DepthPrepass::render()
//descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); //descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet();
descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet;
command->bindDescriptor(descriptorSets); command->bindDescriptor(descriptorSets);
if(graphics->supportMeshShading()) if (graphics->supportMeshShading())
{ {
command->dispatch(instance.numMeshes, 1, 1); command->dispatch(instance.meshes.size(), 1, 1);
} }
else else
{ {
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0; uint32 instanceOffset = 0;
for(const auto& mesh : instance.meshes) for (const auto& [instance, meshData] : instance.meshes)
{ {
uint32 vertexOffset = vertexData->getMeshOffset(mesh.id); if (meshData.numIndices > 0)
if (mesh.indexBuffer != nullptr)
{ {
command->bindIndexBuffer(mesh.indexBuffer); command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset++);
command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset);
} }
else
{
command->draw(vertexData->getMeshVertexCount(mesh.id), 1, vertexOffset, instanceOffset);
}
instanceOffset+=mesh.meshes;
} }
} }
} }
+30 -24
View File
@@ -32,15 +32,16 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform)
MaterialData& matData = materialData[mat->getName()]; MaterialData& matData = materialData[mat->getName()];
matData.material = mat; matData.material = mat;
MaterialInstanceData& matInstanceData = matData.instances[mesh->referencedMaterial->getHandle()->getId()]; MaterialInstanceData& matInstanceData = matData.instances[mesh->referencedMaterial->getHandle()->getId()];
matInstanceData.meshes.add(MeshInstanceData{ for (auto& data : meshData[mesh->id])
.id = mesh->id, {
.instance = InstanceData { matInstanceData.meshes.add(MeshInstanceData{
.transformMatrix = transform.toMatrix(), .instance = InstanceData {
}, .transformMatrix = transform.toMatrix(),
.indexBuffer = mesh->indexBuffer, },
}); .data = data
});
}
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle(); matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
matInstanceData.numMeshes += meshData[mesh->id].size();
} }
void VertexData::createDescriptors() void VertexData::createDescriptors()
@@ -54,13 +55,8 @@ void VertexData::createDescriptors()
Array<MeshData> meshes; Array<MeshData> meshes;
for (auto& inst : matInst.meshes) for (auto& inst : matInst.meshes)
{ {
inst.meshes = 0; meshes.add(inst.data);
for (const auto& mesh : meshData[inst.id]) instanceData.add(inst.instance);
{
meshes.add(mesh);
instanceData.add(inst.instance);
inst.meshes++;
}
} }
matInst.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ matInst.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = { .sourceData = {
@@ -71,7 +67,6 @@ void VertexData::createDescriptors()
.dynamic = false, .dynamic = false,
}); });
matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet(); matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet();
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
matInst.meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ matInst.meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = { .sourceData = {
@@ -81,23 +76,22 @@ void VertexData::createDescriptors()
.numElements = meshes.size(), .numElements = meshes.size(),
.dynamic = false, .dynamic = false,
}); });
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
matInst.descriptorSet->updateBuffer(1, matInst.meshDataBuffer); matInst.descriptorSet->updateBuffer(1, matInst.meshDataBuffer);
matInst.descriptorSet->updateBuffer(2, meshletBuffer); matInst.descriptorSet->updateBuffer(2, meshletBuffer);
matInst.descriptorSet->updateBuffer(3, primitiveIndicesBuffer); matInst.descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
matInst.descriptorSet->updateBuffer(4, vertexIndicesBuffer); matInst.descriptorSet->updateBuffer(4, vertexIndicesBuffer);
matInst.descriptorSet->writeChanges(); matInst.descriptorSet->writeChanges();
matInst.numMeshes = meshes.size();
} }
} }
} }
void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets) void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
{ {
meshlets.reserve(meshlets.size() + loadedMeshlets.size()); meshlets.reserve(meshlets.size() + loadedMeshlets.size());
vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet); vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet);
vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3); primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3);
meshData[id].clear();
uint32 currentMesh = 0; uint32 currentMesh = 0;
while (currentMesh < loadedMeshlets.size()) while (currentMesh < loadedMeshlets.size())
{ {
@@ -127,13 +121,24 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
}); });
currentMesh += numMeshlets; currentMesh += numMeshlets;
} }
meshData[id][0].firstIndex = indices.size();
meshData[id][0].numIndices = loadedIndices.size();
indices.resize(indices.size() + loadedIndices.size());
std::memcpy(indices.data() + meshData[id][0].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32));
indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
.sourceData = {
.size = sizeof(uint32) * indices.size(),
.data = (uint8*)indices.data(),
},
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
});
meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = { .sourceData = {
.size = sizeof(MeshletDescription) * meshlets.size(), .size = sizeof(MeshletDescription) * meshlets.size(),
.data = (uint8*)meshlets.data() .data = (uint8*)meshlets.data()
}, },
.numElements = meshlets.size(), .numElements = meshlets.size(),
.dynamic = true, .dynamic = false,
}); });
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = { .sourceData = {
@@ -141,7 +146,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
.data = (uint8*)vertexIndices.data(), .data = (uint8*)vertexIndices.data(),
}, },
.numElements = vertexIndices.size(), .numElements = vertexIndices.size(),
.dynamic = true, .dynamic = false,
}); });
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = { .sourceData = {
@@ -149,7 +154,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
.data = (uint8*)primitiveIndices.data(), .data = (uint8*)primitiveIndices.data(),
}, },
.numElements = primitiveIndices.size(), .numElements = primitiveIndices.size(),
.dynamic = true, .dynamic = false,
}); });
} }
@@ -269,7 +274,8 @@ void Seele::Meshlet::buildFromIndexBuffer(const Array<uint32>& indices, Array<Me
return i; return i;
} }
} }
assert(false); // it could be in unique vertices but not in meshlet vertices
return -1;
} }
}; };
auto completeMeshlet = [&meshlets, &current, &uniqueVertices]() { auto completeMeshlet = [&meshlets, &current, &uniqueVertices]() {
+12 -11
View File
@@ -39,12 +39,18 @@ public:
{ {
Matrix4 transformMatrix; Matrix4 transformMatrix;
}; };
struct MeshData
{
uint32 numMeshlets = 0;
uint32 meshletOffset = 0;
uint32 firstIndex = 0;
uint32 numIndices = 0;
uint32 indicesOffset = 0;
};
struct MeshInstanceData struct MeshInstanceData
{ {
MeshId id;
InstanceData instance; InstanceData instance;
Gfx::PIndexBuffer indexBuffer; MeshData data;
uint32 meshes;
}; };
struct MaterialInstanceData struct MaterialInstanceData
{ {
@@ -52,7 +58,6 @@ public:
Gfx::OShaderBuffer instanceBuffer; Gfx::OShaderBuffer instanceBuffer;
Gfx::OShaderBuffer meshDataBuffer; Gfx::OShaderBuffer meshDataBuffer;
Gfx::PDescriptorSet descriptorSet; Gfx::PDescriptorSet descriptorSet;
uint32 numMeshes = 0; // not necessarily equal to meshes.size() if a MeshId has multiple meshes
Array<MeshInstanceData> meshes; Array<MeshInstanceData> meshes;
}; };
struct MaterialData struct MaterialData
@@ -60,16 +65,10 @@ public:
PMaterial material; PMaterial material;
Map<uint64, MaterialInstanceData> instances; Map<uint64, MaterialInstanceData> instances;
}; };
struct MeshData
{
uint32 numMeshlets;
uint32 meshletOffset;
uint32 indicesOffset;
};
void resetMeshData(); void resetMeshData();
void updateMesh(PMesh mesh, Component::Transform& transform); void updateMesh(PMesh mesh, Component::Transform& transform);
void createDescriptors(); void createDescriptors();
void loadMesh(MeshId id, Array<Meshlet> meshlets); void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
MeshId allocateVertexData(uint64 numVertices); MeshId allocateVertexData(uint64 numVertices);
uint64 getMeshOffset(MeshId id); uint64 getMeshOffset(MeshId id);
uint64 getMeshVertexCount(MeshId id); uint64 getMeshVertexCount(MeshId id);
@@ -79,6 +78,7 @@ public:
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
virtual Gfx::PDescriptorSet getVertexDataSet() = 0; virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
virtual std::string getTypeName() const = 0; virtual std::string getTypeName() const = 0;
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; } Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
const Map<std::string, MaterialData>& getMaterialData() const { return materialData; } const Map<std::string, MaterialData>& getMaterialData() const { return materialData; }
const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; } const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; }
@@ -111,6 +111,7 @@ protected:
Array<MeshletDescription> meshlets; Array<MeshletDescription> meshlets;
Array<uint8> primitiveIndices; Array<uint8> primitiveIndices;
Array<uint32> vertexIndices; Array<uint32> vertexIndices;
Array<uint32> indices;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
Gfx::ODescriptorLayout instanceDataLayout; Gfx::ODescriptorLayout instanceDataLayout;
// for mesh shading // for mesh shading
+2 -2
View File
@@ -143,7 +143,6 @@ Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
return getComputeCommands()->createComputeCommand(name); return getComputeCommands()->createComputeCommand(name);
} }
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
{ {
OVertexShader shader = new VertexShader(this); OVertexShader shader = new VertexShader(this);
@@ -179,6 +178,7 @@ Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreat
{ {
return pipelineCache->createPipeline(std::move(createInfo)); return pipelineCache->createPipeline(std::move(createInfo));
} }
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
{ {
return pipelineCache->createPipeline(std::move(createInfo)); return pipelineCache->createPipeline(std::move(createInfo));
@@ -399,7 +399,7 @@ void Graphics::pickPhysicalDevice()
{ {
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0)
{ {
meshShadingEnabled = true; //meshShadingEnabled = true;
break; break;
} }
} }