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_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 MAX_MESHLETS_PER_MESH = 512;
@@ -33,7 +33,6 @@ struct Scene
StructuredBuffer<MeshData> meshData;
StructuredBuffer<MeshletDescription> meshletInfos;
StructuredBuffer<uint8_t> primitiveIndices;
StructuredBuffer<uint32_t> vertexIndices;
};
+1 -10
View File
@@ -195,18 +195,10 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
Array<Meshlet> meshlets;
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
Meshlet::buildFromIndexBuffer(indices, meshlets);
vertexData->loadMesh(id, meshlets);
vertexData->loadMesh(id, indices, meshlets);
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]->vertexData = vertexData;
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]->indices = std::move(indices);
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);
vertexData = VertexData::findByTypeName(typeName);
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);
std::string refId;
Serialization::load(buffer, refId);
referencedMaterial = AssetRegistry::findMaterialInstance(refId);
id = vertexData->allocateVertexData(vertexCount);
vertexData->loadMesh(id, meshlets);
vertexData->loadMesh(id, indices, meshlets);
vertexData->deserializeMesh(id, buffer);
}
-1
View File
@@ -14,7 +14,6 @@ public:
VertexData* vertexData;
MeshId id;
uint64 vertexCount;
Gfx::OIndexBuffer indexBuffer;
PMaterialInstanceAsset referencedMaterial;
Array<uint32> indices;
Array<Meshlet> meshlets;
+5 -11
View File
@@ -155,24 +155,18 @@ void BasePass::render()
command->bindDescriptor(descriptorSets);
if (graphics->supportMeshShading())
{
command->dispatch(instance.numMeshes, 1, 1);
command->dispatch(instance.meshes.size(), 1, 1);
}
else
{
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0;
for (const auto& mesh : instance.meshes)
for (const auto& [instance, meshData] : instance.meshes)
{
uint32 vertexOffset = vertexData->getMeshOffset(mesh.id);
if (mesh.indexBuffer != nullptr)
if (meshData.numIndices > 0)
{
command->bindIndexBuffer(mesh.indexBuffer);
command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset);
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, 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_SCENE_DATA] = instance.descriptorSet;
command->bindDescriptor(descriptorSets);
if(graphics->supportMeshShading())
if (graphics->supportMeshShading())
{
command->dispatch(instance.numMeshes, 1, 1);
command->dispatch(instance.meshes.size(), 1, 1);
}
else
{
command->bindIndexBuffer(vertexData->getIndexBuffer());
uint32 instanceOffset = 0;
for(const auto& mesh : instance.meshes)
for (const auto& [instance, meshData] : instance.meshes)
{
uint32 vertexOffset = vertexData->getMeshOffset(mesh.id);
if (mesh.indexBuffer != nullptr)
if (meshData.numIndices > 0)
{
command->bindIndexBuffer(mesh.indexBuffer);
command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset);
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, 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()];
matData.material = mat;
MaterialInstanceData& matInstanceData = matData.instances[mesh->referencedMaterial->getHandle()->getId()];
matInstanceData.meshes.add(MeshInstanceData{
.id = mesh->id,
.instance = InstanceData {
.transformMatrix = transform.toMatrix(),
},
.indexBuffer = mesh->indexBuffer,
});
for (auto& data : meshData[mesh->id])
{
matInstanceData.meshes.add(MeshInstanceData{
.instance = InstanceData {
.transformMatrix = transform.toMatrix(),
},
.data = data
});
}
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
matInstanceData.numMeshes += meshData[mesh->id].size();
}
void VertexData::createDescriptors()
@@ -54,13 +55,8 @@ void VertexData::createDescriptors()
Array<MeshData> meshes;
for (auto& inst : matInst.meshes)
{
inst.meshes = 0;
for (const auto& mesh : meshData[inst.id])
{
meshes.add(mesh);
instanceData.add(inst.instance);
inst.meshes++;
}
meshes.add(inst.data);
instanceData.add(inst.instance);
}
matInst.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
@@ -71,7 +67,6 @@ void VertexData::createDescriptors()
.dynamic = false,
});
matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet();
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
matInst.meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
@@ -81,23 +76,22 @@ void VertexData::createDescriptors()
.numElements = meshes.size(),
.dynamic = false,
});
matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
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();
}
}
}
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());
vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet);
vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3);
meshData[id].clear();
primitiveIndices.reserve(primitiveIndices.size() + loadedMeshlets.size() * Gfx::numPrimitivesPerMeshlet * 3);
uint32 currentMesh = 0;
while (currentMesh < loadedMeshlets.size())
{
@@ -127,13 +121,24 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
});
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{
.sourceData = {
.size = sizeof(MeshletDescription) * meshlets.size(),
.data = (uint8*)meshlets.data()
},
.numElements = meshlets.size(),
.dynamic = true,
.dynamic = false,
});
vertexIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
@@ -141,7 +146,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
.data = (uint8*)vertexIndices.data(),
},
.numElements = vertexIndices.size(),
.dynamic = true,
.dynamic = false,
});
primitiveIndicesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
@@ -149,7 +154,7 @@ void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
.data = (uint8*)primitiveIndices.data(),
},
.numElements = primitiveIndices.size(),
.dynamic = true,
.dynamic = false,
});
}
@@ -269,7 +274,8 @@ void Seele::Meshlet::buildFromIndexBuffer(const Array<uint32>& indices, Array<Me
return i;
}
}
assert(false);
// it could be in unique vertices but not in meshlet vertices
return -1;
}
};
auto completeMeshlet = [&meshlets, &current, &uniqueVertices]() {
+12 -11
View File
@@ -39,12 +39,18 @@ public:
{
Matrix4 transformMatrix;
};
struct MeshData
{
uint32 numMeshlets = 0;
uint32 meshletOffset = 0;
uint32 firstIndex = 0;
uint32 numIndices = 0;
uint32 indicesOffset = 0;
};
struct MeshInstanceData
{
MeshId id;
InstanceData instance;
Gfx::PIndexBuffer indexBuffer;
uint32 meshes;
MeshData data;
};
struct MaterialInstanceData
{
@@ -52,7 +58,6 @@ public:
Gfx::OShaderBuffer instanceBuffer;
Gfx::OShaderBuffer meshDataBuffer;
Gfx::PDescriptorSet descriptorSet;
uint32 numMeshes = 0; // not necessarily equal to meshes.size() if a MeshId has multiple meshes
Array<MeshInstanceData> meshes;
};
struct MaterialData
@@ -60,16 +65,10 @@ public:
PMaterial material;
Map<uint64, MaterialInstanceData> instances;
};
struct MeshData
{
uint32 numMeshlets;
uint32 meshletOffset;
uint32 indicesOffset;
};
void resetMeshData();
void updateMesh(PMesh mesh, Component::Transform& transform);
void createDescriptors();
void loadMesh(MeshId id, Array<Meshlet> meshlets);
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
MeshId allocateVertexData(uint64 numVertices);
uint64 getMeshOffset(MeshId id);
uint64 getMeshVertexCount(MeshId id);
@@ -79,6 +78,7 @@ public:
virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0;
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
virtual std::string getTypeName() const = 0;
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
const Map<std::string, MaterialData>& getMaterialData() const { return materialData; }
const Array<MeshData>& getMeshData(MeshId id) { return meshData[id]; }
@@ -111,6 +111,7 @@ protected:
Array<MeshletDescription> meshlets;
Array<uint8> primitiveIndices;
Array<uint32> vertexIndices;
Array<uint32> indices;
Gfx::PGraphics graphics;
Gfx::ODescriptorLayout instanceDataLayout;
// for mesh shading
+2 -2
View File
@@ -143,7 +143,6 @@ Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
return getComputeCommands()->createComputeCommand(name);
}
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
{
OVertexShader shader = new VertexShader(this);
@@ -179,6 +178,7 @@ Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreat
{
return pipelineCache->createPipeline(std::move(createInfo));
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo 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)
{
meshShadingEnabled = true;
//meshShadingEnabled = true;
break;
}
}