implement global index buffer
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ public:
|
||||
VertexData* vertexData;
|
||||
MeshId id;
|
||||
uint64 vertexCount;
|
||||
Gfx::OIndexBuffer indexBuffer;
|
||||
PMaterialInstanceAsset referencedMaterial;
|
||||
Array<uint32> indices;
|
||||
Array<Meshlet> meshlets;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, ¤t, &uniqueVertices]() {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user