From 52c7fce9310e37a886c1e0b58207fce19199730a Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Sun, 26 Nov 2023 11:27:39 +0100 Subject: [PATCH] implement global index buffer --- res/shaders/lib/Scene.slang | 3 +- src/Editor/Asset/MeshLoader.cpp | 11 +--- src/Engine/Graphics/Mesh.cpp | 9 +--- src/Engine/Graphics/Mesh.h | 1 - src/Engine/Graphics/RenderPass/BasePass.cpp | 16 ++---- .../Graphics/RenderPass/DepthPrepass.cpp | 18 +++---- src/Engine/Graphics/VertexData.cpp | 54 ++++++++++--------- src/Engine/Graphics/VertexData.h | 23 ++++---- src/Engine/Graphics/Vulkan/Graphics.cpp | 4 +- 9 files changed, 58 insertions(+), 81 deletions(-) diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index 4195371..d5613c5 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -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; StructuredBuffer meshletInfos; StructuredBuffer primitiveIndices; - StructuredBuffer vertexIndices; }; diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index a3fc41e..9651743 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -195,18 +195,10 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array 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 Arraymeshlets = std::move(meshlets); globalMeshes[meshIndex]->indices = std::move(indices); globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices; - globalMeshes[meshIndex]->indexBuffer = std::move(indexBuffer); } } diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp index 5967307..9633140 100644 --- a/src/Engine/Graphics/Mesh.cpp +++ b/src/Engine/Graphics/Mesh.cpp @@ -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); } diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h index 36034b7..90a4c03 100644 --- a/src/Engine/Graphics/Mesh.h +++ b/src/Engine/Graphics/Mesh.h @@ -14,7 +14,6 @@ public: VertexData* vertexData; MeshId id; uint64 vertexCount; - Gfx::OIndexBuffer indexBuffer; PMaterialInstanceAsset referencedMaterial; Array indices; Array meshlets; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 7b732a0..dc9afc9 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -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; } } } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index cead9c9..71be909 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -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; } } } diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 77d02d9..4d32599 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -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 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 loadedMeshlets) +void VertexData::loadMesh(MeshId id, Array loadedIndices, Array 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 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 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 loadedMeshlets) .data = (uint8*)primitiveIndices.data(), }, .numElements = primitiveIndices.size(), - .dynamic = true, + .dynamic = false, }); } @@ -269,7 +274,8 @@ void Seele::Meshlet::buildFromIndexBuffer(const Array& indices, Array meshes; }; struct MaterialData @@ -60,16 +65,10 @@ public: PMaterial material; Map 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 meshlets); + void loadMesh(MeshId id, Array indices, Array 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& getMaterialData() const { return materialData; } const Array& getMeshData(MeshId id) { return meshData[id]; } @@ -111,6 +111,7 @@ protected: Array meshlets; Array primitiveIndices; Array vertexIndices; + Array indices; Gfx::PGraphics graphics; Gfx::ODescriptorLayout instanceDataLayout; // for mesh shading diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 2704b7a..6044a38 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -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; } }