diff --git a/Seele.natvis b/Seele.natvis
index 2c863d3..462fe75 100644
--- a/Seele.natvis
+++ b/Seele.natvis
@@ -1,72 +1,81 @@
-
- {{ size={arraySize} }}
-
- - arraySize
- - allocated
-
- arraySize
- _data
-
-
-
-
- {{ size={_size} }}
-
- - _size
-
- _size
- root
- next
- data
-
-
-
-
- [{key}, {value}]
-
- - key
- - value
-
-
-
- {{ size={_size} }
-
- - _size
- - comp
-
- _size
- nodeContainer._data
-
-
-
-
- [{pair}]
-
- - pair
- - leftChild
- - rightChild
-
-
-
- empty
- [{nodeContainer._data[node].pair}]
-
- nodeContainer._data[node].pair
-
-
-
- empty
- RefPtr {*object}
-
- object
-
-
-
- UniquePtr {*handle}
-
- handle
-
-
+
+ {{ size={arraySize} }}
+
+ - arraySize
+ - allocated
+
+ arraySize
+ _data
+
+
+
+
+ {{ size={$T2} }}
+
+
+ $T2
+ _data
+
+
+
+
+ {{ size={_size} }}
+
+ - _size
+
+ _size
+ root
+ next
+ data
+
+
+
+
+ [{key}, {value}]
+
+ - key
+ - value
+
+
+
+ {{ size={_size} }
+
+ - _size
+ - comp
+
+ _size
+ nodeContainer._data
+
+
+
+
+ [{pair}]
+
+ - pair
+ - leftChild
+ - rightChild
+
+
+
+ empty
+ [{nodeContainer._data[node].pair}]
+
+ nodeContainer._data[node].pair
+
+
+
+ empty
+ RefPtr {*object}
+
+ object
+
+
+
+ UniquePtr {*handle}
+
+ handle
+
+
diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang
index 3d091f1..b607634 100644
--- a/res/shaders/MeshletBasePass.slang
+++ b/res/shaders/MeshletBasePass.slang
@@ -1,8 +1,8 @@
import Common;
import BRDF;
import Meshlet;
-import Scene;
import VertexData;
+import MaterialParameter;
struct MeshPayload
{
@@ -47,14 +47,17 @@ void taskMain(
MeshData mesh = pScene.meshData[groupID];
for(uint i = threadID; i < MAX_MESHLETS_PER_MESH; i += TASK_GROUP_SIZE)
{
- uint m = mesh.meshletOffset + min(mesh.numMeshlets, i);
- MeshletDescription meshlet = pScene.meshlets.meshletInfos[m];
- //if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum))
+ if(i < mesh.numMeshlets)
{
- uint index;
- InterlockedAdd(head, 1, index);
- p.meshletId[index] = m;
- p.instanceId[index] = groupID;
+ uint m = mesh.meshletOffset + i;
+ MeshletDescription meshlet = pScene.meshletInfos[m];
+ //if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum))
+ {
+ uint index;
+ InterlockedAdd(head, 1, index);
+ p.meshletId[index] = m;
+ p.instanceId[index] = groupID;
+ }
}
}
GroupMemoryBarrierWithGroupSync();
@@ -71,6 +74,12 @@ struct PrimitiveAttributes
uint cull: SV_CullPrimitive;
};
+struct MeshOutput
+{
+ FragmentParameter parameter : PARAMETER;
+ float4 position_CS : SV_Position;
+};
+
[numthreads(MESH_GROUP_SIZE, 1, 1)]
[outputtopology("triangle")]
[shader("mesh")]
@@ -78,7 +87,7 @@ void meshMain(
in uint threadID: SV_GroupIndex,
in uint groupID: SV_GroupID,
in payload MeshPayload meshPayload,
- out Vertices vertices,
+ out Vertices vertices,
out Indices indices
){
InstanceData inst = pScene.instances[meshPayload.instanceId[groupID]];
@@ -92,10 +101,10 @@ void meshMain(
InterlockedMax(gs_numVertices, v + 1);
{
int vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
- gs_vertices[v] = pVertexData.getAttributes(md.indexOffset + vertexIndex, inst);
+ gs_vertices[v] = pVertexData.getAttributes(md.indicesOffset + vertexIndex, inst.transformMatrix);
}
}
-
+ GroupMemoryBarrierWithGroupSync();
const uint primitiveLoops = (MAX_PRIMITIVES + MESH_GROUP_SIZE - 1) / MESH_GROUP_SIZE;
for(uint loop = 0; loop < primitiveLoops; ++loop)
{
@@ -103,15 +112,12 @@ void meshMain(
p = min(p, m.primitiveCount - 1);
InterlockedMax(gs_numPrimitives, p + 1);
{
- uint8_t local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
- uint8_t local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
- uint8_t local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
- uint32_t idx0 = pScene.vertexIndices[m.vertexOffset + local_idx0];
- uint32_t idx1 = pScene.vertexIndices[m.vertexOffset + local_idx1];
- uint32_t idx2 = pScene.vertexIndices[m.vertexOffset + local_idx2];
- gs_indices[p * 3 + 0] = idx0;
- gs_indices[p * 3 + 1] = idx1;
- gs_indices[p * 3 + 2] = idx2;
+ uint32_t local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
+ uint32_t local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
+ uint32_t local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
+ gs_indices[p].x = local_idx0;
+ gs_indices[p].y = local_idx1;
+ gs_indices[p].z = local_idx2;
}
}
GroupMemoryBarrierWithGroupSync();
@@ -120,12 +126,16 @@ void meshMain(
uint v = threadID;
v = min(v, m.vertexCount - 1);
- vertices[v] = gs_vertices[v];
+ FragmentParameter parameter = gs_vertices[v].getParameter(inst.transformMatrix);
+ vertices[v].parameter = parameter;
+ vertices[v].position_CS = parameter.position_CS;
if(vertexLoops >= 1)
{
uint v = threadID + MESH_GROUP_SIZE;
v = min(v, m.vertexCount - 1);
- vertices[v] = gs_vertices[v];
+ FragmentParameter parameter = gs_vertices[v].getParameter(inst.transformMatrix);
+ vertices[v].parameter = parameter;
+ vertices[v].position_CS = parameter.position_CS;
}
uint p = threadID;
@@ -134,19 +144,19 @@ void meshMain(
if(primitiveLoops >= 1)
{
- uint p = threadID + MESH_GROUP_SIZE;
+ p += MESH_GROUP_SIZE;
p = min(p, m.primitiveCount - 1);
indices[p] = gs_indices[p];
}
if(primitiveLoops >= 2)
{
- uint p = threadID + 2 * MESH_GROUP_SIZE;
+ p += MESH_GROUP_SIZE;
p = min(p, m.primitiveCount - 1);
indices[p] = gs_indices[p];
}
if(primitiveLoops >= 3)
{
- uint p = threadID + 3 * MESH_GROUP_SIZE;
+ p += MESH_GROUP_SIZE;
p = min(p, m.primitiveCount - 1);
indices[p] = gs_indices[p];
}
diff --git a/res/shaders/lib/MaterialParameter.slang b/res/shaders/lib/MaterialParameter.slang
index 6284b55..81fb70a 100644
--- a/res/shaders/lib/MaterialParameter.slang
+++ b/res/shaders/lib/MaterialParameter.slang
@@ -20,15 +20,15 @@ struct LightingParameter
// data passed to fragment shader
struct FragmentParameter
{
- float3 position_TS;
- float3 viewDir_TS;
- float3 normal_WS;
- float3 tangent_WS;
- float3 biTangent_WS;
- float3 position_WS;
- float4 position_CS;
- float2 texCoords;
- float3 vertexColor;
+ float4 position_CS : SV_Position;
+ float3 position_TS : POSITION0;
+ float3 viewDir_TS : POSITION1;
+ float3 normal_WS : NORMAL0;
+ float3 tangent_WS : TANGENT0;
+ float3 biTangent_WS : TANGENT1;
+ float3 position_WS : POSITION2;
+ float2 texCoords : TEXCOORD0;
+ float3 vertexColor : COLOR0;
MaterialParameter getMaterialParameter()
{
MaterialParameter result;
diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp
index f804c03..a3fc41e 100644
--- a/src/Editor/Asset/MeshLoader.cpp
+++ b/src/Editor/Asset/MeshLoader.cpp
@@ -194,68 +194,9 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array meshlets;
meshlets.reserve(indices.size() / (3ull * Gfx::numPrimitivesPerMeshlet));
- std::set uniqueVertices;
- Meshlet current = {
- .numVertices = 0,
- .numPrimitives = 0,
- };
- auto insertAndGetIndex = [&uniqueVertices, ¤t](uint32 index) -> int8_t
- {
- auto [it, inserted] = uniqueVertices.insert(index);
- if (inserted)
- {
- if (current.numVertices == Gfx::numVerticesPerMeshlet)
- {
- return -1;
- }
- current.uniqueVertices[current.numVertices] = index;
- return current.numVertices++;
- }
- else
- {
- for (uint32 i = 0; i < current.numVertices; ++i)
- {
- if (current.uniqueVertices[i] == index)
- {
- return i;
- }
- }
- assert(false);
- }
- };
- auto completeMeshlet = [&meshlets, ¤t, &uniqueVertices]() {
- meshlets.add(current);
- current = {
- .numVertices = 0,
- .numPrimitives = 0,
- };
- uniqueVertices.clear();
- };
- for (size_t faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex)
- {
- auto i1 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[0]);
- auto i2 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[1]);
- auto i3 = insertAndGetIndex(mesh->mFaces[faceIndex].mIndices[2]);
- if (i1 == -1 || i2 == -1 || i3 == -1)
- {
- completeMeshlet();
- }
- current.primitiveLayout[current.numPrimitives * 3 + 0] = i1;
- current.primitiveLayout[current.numPrimitives * 3 + 1] = i2;
- current.primitiveLayout[current.numPrimitives * 3 + 2] = i3;
- current.numPrimitives++;
- if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
- {
- completeMeshlet();
- }
- }
- if (!uniqueVertices.empty())
- {
- completeMeshlet();
- }
+ Meshlet::buildFromIndexBuffer(indices, meshlets);
vertexData->loadMesh(id, meshlets);
-
collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
IndexBufferCreateInfo idxInfo;
diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp
index 19eb1eb..7ecfc79 100644
--- a/src/Editor/main.cpp
+++ b/src/Editor/main.cpp
@@ -37,39 +37,39 @@ int main()
graphics->init(initializer);
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
vd->init(graphics);
- PWindowManager windowManager = new WindowManager();
+ OWindowManager windowManager = new WindowManager();
AssetRegistry::init(sourcePath / "Assets", graphics);
AssetImporter::init(graphics);
AssetImporter::importFont(FontImportArgs{
.filePath = "./fonts/Calibri.ttf",
});
- AssetImporter::importMesh(MeshImportArgs{
- .filePath = sourcePath / "old_resources/models/arena.fbx",
- });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath = sourcePath / "old_resources/models/arena.fbx",
+ // });
AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "old_resources/models/train.fbx",
});
- AssetImporter::importMesh(MeshImportArgs{
- .filePath= sourcePath / "old_resources/models/bird.fbx",
- });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath= sourcePath / "old_resources/models/bird.fbx",
+ // });
AssetImporter::importMesh(MeshImportArgs{
.filePath= sourcePath / "old_resources/models/cube.fbx",
});
- AssetImporter::importMesh(MeshImportArgs{
- .filePath= sourcePath / "old_resources/models/flameThrower.fbx",
- });
- AssetImporter::importMesh(MeshImportArgs{
- .filePath= sourcePath / "old_resources/models/player.fbx",
- });
- AssetImporter::importMesh(MeshImportArgs{
- .filePath= sourcePath / "old_resources/models/shotgun.fbx",
- });
- AssetImporter::importMesh(MeshImportArgs{
- .filePath= sourcePath / "old_resources/models/track.fbx",
- });
- AssetImporter::importMesh(MeshImportArgs{
- .filePath= sourcePath / "old_resources/models/zombie.fbx",
- });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath= sourcePath / "old_resources/models/flameThrower.fbx",
+ // });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath= sourcePath / "old_resources/models/player.fbx",
+ // });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath= sourcePath / "old_resources/models/shotgun.fbx",
+ // });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath= sourcePath / "old_resources/models/track.fbx",
+ // });
+ //AssetImporter::importMesh(MeshImportArgs{
+ // .filePath= sourcePath / "old_resources/models/zombie.fbx",
+ // });
AssetImporter::importTexture(TextureImportArgs{
.filePath= sourcePath / "old_resources/textures/Dirt.png",
diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h
index 6af956c..1e85267 100644
--- a/src/Engine/Containers/Array.h
+++ b/src/Engine/Containers/Array.h
@@ -602,17 +602,18 @@ private:
// The array is not big enough, so we make a new one
T *newData = allocateArray(newSize);
- // And move the current elements into that one
- for(size_type i = 0; i < arraySize; ++i)
- {
- newData[i] = std::forward(_data[i]);
- }
if constexpr (std::is_integral_v || std::is_floating_point_v)
{
+ std::memcpy(newData, _data, sizeof(T) * arraySize);
std::memset(&newData[arraySize], 0, sizeof(T) * (newSize - arraySize));
}
else
{
+ // And move the current elements into that one
+ for(size_type i = 0; i < arraySize; ++i)
+ {
+ newData[i] = std::forward(_data[i]);
+ }
// As well as default initialize the others
for (size_type i = arraySize; i < newSize; ++i)
{
diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp
index 1239f38..7b732a0 100644
--- a/src/Engine/Graphics/RenderPass/BasePass.cpp
+++ b/src/Engine/Graphics/RenderPass/BasePass.cpp
@@ -36,7 +36,14 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
lightCullingLayout->create();
basePassLayout->addDescriptorLayout(INDEX_LIGHT_CULLING, lightCullingLayout);
- graphics->getShaderCompiler()->registerRenderPass("BasePass", "LegacyBasePass", true, true, "BasePass");
+ if (graphics->supportMeshShading())
+ {
+ graphics->getShaderCompiler()->registerRenderPass("BasePass", "MeshletBasePass", true, true, "BasePass", true, true, "MeshletBasePass");
+ }
+ else
+ {
+ graphics->getShaderCompiler()->registerRenderPass("BasePass", "LegacyBasePass", true, true, "BasePass");
+ }
}
BasePass::~BasePass()
@@ -124,6 +131,7 @@ void BasePass::render()
pipelineInfo.pipelineLayout = std::move(layout);
pipelineInfo.renderPass = renderPass;
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL;
+ pipelineInfo.rasterizationState.lineWidth = 10.f;
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp
index 64e84c3..cead9c9 100644
--- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp
+++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp
@@ -20,7 +20,14 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
depthPrepassLayout = graphics->createPipelineLayout();
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout);
- graphics->getShaderCompiler()->registerRenderPass("DepthPass", "LegacyBasePass");
+ if (graphics->supportMeshShading())
+ {
+ graphics->getShaderCompiler()->registerRenderPass("DepthPass", "MeshletBasePass", false, false, "", true, true, "MeshletBasePass");
+ }
+ else
+ {
+ graphics->getShaderCompiler()->registerRenderPass("DepthPass", "LegacyBasePass");
+ }
}
DepthPrepass::~DepthPrepass()
diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp
index ff464d7..033e5c6 100644
--- a/src/Engine/Graphics/StaticMeshVertexData.cpp
+++ b/src/Engine/Graphics/StaticMeshVertexData.cpp
@@ -111,7 +111,7 @@ void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer)
loadNormals(id, nor);
loadTangents(id, tan);
loadBiTangents(id, bit);
- loadBiTangents(id, col);
+ loadColors(id, col);
}
void StaticMeshVertexData::init(Gfx::PGraphics graphics)
diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp
index 8c08735..eb79f01 100644
--- a/src/Engine/Graphics/VertexData.cpp
+++ b/src/Engine/Graphics/VertexData.cpp
@@ -6,10 +6,11 @@
#include "Graphics/Descriptor.h"
#include "Component/Mesh.h"
#include "Graphics/Shader.h"
+#include
using namespace Seele;
-constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
+constexpr static uint64 NUM_DEFAULT_ELEMENTS = 16 * 1024;
void VertexData::resetMeshData()
{
@@ -17,7 +18,6 @@ void VertexData::resetMeshData()
{
mat.material->getDescriptorLayout()->reset();
}
- materialData.clear();
if (dirty)
{
updateBuffers();
@@ -25,7 +25,7 @@ void VertexData::resetMeshData()
}
}
-void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh)
+void VertexData::addMesh(PMesh mesh)
{
PMaterial mat = mesh->referencedMaterial->getHandle()->getBaseMaterial();
MaterialData& matData = materialData[mat->getName()];
@@ -34,15 +34,66 @@ void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh)
matInstanceData.meshes.add(MeshInstanceData{
.id = mesh->id,
.instance = InstanceData {
- .transformMatrix = transform.toMatrix(),
+ .transformMatrix = Matrix4(),
},
.indexBuffer = mesh->indexBuffer,
});
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
- matInstanceData.materialInstance->updateDescriptor();
matInstanceData.numMeshes += meshData[mesh->id].size();
}
+void VertexData::removeMesh(PMesh mesh)
+{
+ PMaterial mat = mesh->referencedMaterial->getHandle()->getBaseMaterial();
+ MaterialData& matData = materialData[mat->getName()];
+ matData.material = mat;
+ MaterialInstanceData& matInstanceData = matData.instances[mesh->referencedMaterial->getHandle()->getId()];
+ matInstanceData.meshes.remove_if([&mesh](const MeshInstanceData& data) {
+ return data.id == mesh->id;
+ });
+ matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
+ matInstanceData.numMeshes -= meshData[mesh->id].size();
+}
+
+void VertexData::updateInstances()
+{
+ instanceDataLayout->reset();
+ for (const auto& [_, mat] : materialData)
+ {
+ for (auto& [_, matInst] : mat.instances)
+ {
+ Array instanceData;
+ for (auto& inst : matInst.meshes)
+ {
+ inst.meshes = 0;
+ for (const auto& mesh : meshData[inst.id])
+ {
+ instanceData.add(inst.instance);
+ inst.meshes++;
+ }
+ }
+ matInst.instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
+ .sourceData = {
+ .size = sizeof(InstanceData) * instanceData.size(),
+ .data = (uint8*)instanceData.data(),
+ },
+ .numElements = instanceData.size(),
+ .dynamic = false,
+ });
+ matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet();
+ matInst.descriptorSet->updateBuffer(0, matInst.instanceBuffer);
+ if (graphics->supportMeshShading())
+ {
+ matInst.descriptorSet->updateBuffer(1, matInst.meshDataBuffer);
+ matInst.descriptorSet->updateBuffer(2, meshletBuffer);
+ matInst.descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
+ matInst.descriptorSet->updateBuffer(4, vertexIndicesBuffer);
+ }
+ matInst.descriptorSet->writeChanges();
+ }
+ }
+}
+
void VertexData::createDescriptors()
{
instanceDataLayout->reset();
@@ -50,14 +101,12 @@ void VertexData::createDescriptors()
{
for (auto& [_, matInst] : mat.instances)
{
- Array instanceData;
Array meshes;
for (auto& inst : matInst.meshes)
{
inst.meshes = 0;
for (const auto& mesh : meshData[inst.id])
{
- instanceData.add(inst.instance);
meshes.add(mesh);
inst.meshes++;
}
@@ -95,6 +144,9 @@ void VertexData::createDescriptors()
void VertexData::loadMesh(MeshId id, 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();
uint32 currentMesh = 0;
while (currentMesh < loadedMeshlets.size())
@@ -239,3 +291,69 @@ void Meshlet::load(ArchiveBuffer& buffer)
Serialization::load(buffer, numVertices);
Serialization::load(buffer, numPrimitives);
}
+
+void Seele::Meshlet::buildFromIndexBuffer(const Array& indices, Array& meshlets)
+{
+ std::set uniqueVertices;
+ Meshlet current = {
+ .numVertices = 0,
+ .numPrimitives = 0,
+ };
+ auto insertAndGetIndex = [&uniqueVertices, ¤t](uint32 index) -> int8_t
+ {
+ auto [it, inserted] = uniqueVertices.insert(index);
+ if (inserted)
+ {
+ if (current.numVertices == Gfx::numVerticesPerMeshlet)
+ {
+ return -1;
+ }
+ current.uniqueVertices[current.numVertices] = index;
+ return current.numVertices++;
+ }
+ else
+ {
+ for (uint32 i = 0; i < current.numVertices; ++i)
+ {
+ if (current.uniqueVertices[i] == index)
+ {
+ return i;
+ }
+ }
+ assert(false);
+ }
+ };
+ auto completeMeshlet = [&meshlets, ¤t, &uniqueVertices]() {
+ meshlets.add(current);
+ current = {
+ .numVertices = 0,
+ .numPrimitives = 0,
+ };
+ uniqueVertices.clear();
+ };
+ for (size_t faceIndex = 0; faceIndex < indices.size() / 3; ++faceIndex)
+ {
+ auto i1 = insertAndGetIndex(indices[faceIndex * 3 + 0]);
+ auto i2 = insertAndGetIndex(indices[faceIndex * 3 + 1]);
+ auto i3 = insertAndGetIndex(indices[faceIndex * 3 + 2]);
+ if (i1 == -1 || i2 == -1 || i3 == -1)
+ {
+ completeMeshlet();
+ i1 = insertAndGetIndex(indices[faceIndex * 3 + 0]);
+ i2 = insertAndGetIndex(indices[faceIndex * 3 + 1]);
+ i3 = insertAndGetIndex(indices[faceIndex * 3 + 2]);
+ }
+ current.primitiveLayout[current.numPrimitives * 3 + 0] = i1;
+ current.primitiveLayout[current.numPrimitives * 3 + 1] = i2;
+ current.primitiveLayout[current.numPrimitives * 3 + 2] = i3;
+ current.numPrimitives++;
+ if (current.numPrimitives == Gfx::numPrimitivesPerMeshlet)
+ {
+ completeMeshlet();
+ }
+ }
+ if (!uniqueVertices.empty())
+ {
+ completeMeshlet();
+ }
+}
diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h
index 50aedb5..df6ac98 100644
--- a/src/Engine/Graphics/VertexData.h
+++ b/src/Engine/Graphics/VertexData.h
@@ -17,6 +17,10 @@ struct MeshId
{
return id <=> other.id;
}
+ bool operator==(const MeshId& other) const
+ {
+ return id == other.id;
+ }
};
struct Meshlet
{
@@ -26,6 +30,7 @@ struct Meshlet
uint32 numPrimitives;
void save(ArchiveBuffer& buffer) const;
void load(ArchiveBuffer& buffer);
+ static void buildFromIndexBuffer(const Array& indices, Array& meshlets);
};
class VertexData
{
@@ -47,7 +52,7 @@ public:
Gfx::OShaderBuffer instanceBuffer;
Gfx::OShaderBuffer meshDataBuffer;
Gfx::PDescriptorSet descriptorSet;
- uint32 numMeshes; // not necessarily equal to meshes.size() if a MeshId has multiple meshes
+ uint32 numMeshes = 0; // not necessarily equal to meshes.size() if a MeshId has multiple meshes
Array meshes;
};
struct MaterialData
@@ -62,7 +67,9 @@ public:
uint32 indicesOffset;
};
void resetMeshData();
- void updateMesh(const Component::Transform& transform, PMesh mesh);
+ void addMesh(PMesh mesh);
+ void removeMesh(PMesh mesh);
+ void updateInstances();
void createDescriptors();
void loadMesh(MeshId id, Array meshlets);
MeshId allocateVertexData(uint64 numVertices);
diff --git a/src/Engine/Graphics/Vulkan/Allocator.cpp b/src/Engine/Graphics/Vulkan/Allocator.cpp
index 300c756..72699bb 100644
--- a/src/Engine/Graphics/Vulkan/Allocator.cpp
+++ b/src/Engine/Graphics/Vulkan/Allocator.cpp
@@ -327,7 +327,7 @@ OStagingBuffer StagingManager::create(uint64 size)
.pNext = nullptr,
.flags = 0,
.size = size,
- .usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+ .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &queueIndex,
diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp
index 5fbd3f4..2704b7a 100644
--- a/src/Engine/Graphics/Vulkan/Graphics.cpp
+++ b/src/Engine/Graphics/Vulkan/Graphics.cpp
@@ -359,11 +359,15 @@ void Graphics::pickPhysicalDevice()
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
VkPhysicalDevice bestDevice = VK_NULL_HANDLE;
uint32 deviceRating = 0;
+ features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+ features.pNext = &features12;
+ features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+ features12.pNext = nullptr;
for (auto dev : physicalDevices)
{
uint32 currentRating = 0;
vkGetPhysicalDeviceProperties(dev, &props);
- vkGetPhysicalDeviceFeatures(dev, &features);
+ vkGetPhysicalDeviceFeatures2(dev, &features);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
@@ -382,8 +386,9 @@ void Graphics::pickPhysicalDevice()
}
}
physicalDevice = bestDevice;
+
vkGetPhysicalDeviceProperties(physicalDevice, &props);
- vkGetPhysicalDeviceFeatures(physicalDevice, &features);
+ vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
if (Gfx::useMeshShading)
{
uint32 count = 0;
@@ -500,31 +505,25 @@ void Graphics::createDevice(GraphicsInitializer initializer)
*currentPriority++ = 1.0f;
}
}
- VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {
- .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
- .shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
- .descriptorBindingPartiallyBound = VK_TRUE,
- .descriptorBindingVariableDescriptorCount = VK_TRUE,
- .runtimeDescriptorArray = VK_TRUE,
- };
VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
+ .pNext = nullptr,
.taskShader = VK_TRUE,
.meshShader = VK_TRUE,
};
if (supportMeshShading())
{
- descriptorIndexing.pNext = &enabledMeshShaderFeatures;
+ features12.pNext = &enabledMeshShaderFeatures;
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
}
VkDeviceCreateInfo deviceInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .pNext = &descriptorIndexing,
+ .pNext = &features12,
.queueCreateInfoCount = (uint32)queueInfos.size(),
.pQueueCreateInfos = queueInfos.data(),
.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(),
.ppEnabledExtensionNames = initializer.deviceExtensions.data(),
- .pEnabledFeatures = &features,
+ .pEnabledFeatures = &features.features,
};
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h
index bf13959..98e9fd5 100644
--- a/src/Engine/Graphics/Vulkan/Graphics.h
+++ b/src/Engine/Graphics/Vulkan/Graphics.h
@@ -91,7 +91,8 @@ protected:
thread_local static OCommandPool transferCommands;
thread_local static OCommandPool dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
- VkPhysicalDeviceFeatures features;
+ VkPhysicalDeviceFeatures2 features;
+ VkPhysicalDeviceVulkan12Features features12;
VkDebugReportCallbackEXT callback;
Map allocatedFramebuffers;
OAllocator allocator;
diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp
index 58187a0..a55301c 100644
--- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp
+++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp
@@ -358,7 +358,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
if (graphicsPipelines.contains(hash))
{
- std::cout << "Caching pipeline" << std::endl;
return graphicsPipelines[hash];
}
VkPipeline pipelineHandle;
diff --git a/src/Engine/Graphics/Vulkan/Window.cpp b/src/Engine/Graphics/Vulkan/Window.cpp
index 61ab2db..e334405 100644
--- a/src/Engine/Graphics/Vulkan/Window.cpp
+++ b/src/Engine/Graphics/Vulkan/Window.cpp
@@ -257,14 +257,14 @@ void Window::chooseSwapSurfaceFormat()
void Window::chooseSwapPresentMode()
{
- for (const auto& supportedPresentMode : supportedPresentModes)
+ /*for (const auto& supportedPresentMode : supportedPresentModes)
{
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
{
presentMode = supportedPresentMode;
return;
}
- }
+ }*/
presentMode = VK_PRESENT_MODE_FIFO_KHR;
}
diff --git a/src/Engine/Material/MaterialInstance.cpp b/src/Engine/Material/MaterialInstance.cpp
index 99cd494..04287f6 100644
--- a/src/Engine/Material/MaterialInstance.cpp
+++ b/src/Engine/Material/MaterialInstance.cpp
@@ -85,6 +85,7 @@ void MaterialInstance::setBaseMaterial(PMaterialAsset asset)
);
}
baseMaterial = asset;
+ updateDescriptor();
}
void MaterialInstance::save(ArchiveBuffer& buffer) const
diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h
index 6989cc8..1b4bb67 100644
--- a/src/Engine/Scene/Scene.h
+++ b/src/Engine/Scene/Scene.h
@@ -44,6 +44,16 @@ public:
{
registry.view().each(func);
}
+ template
+ auto constructCallback()
+ {
+ return registry.on_construct();
+ }
+ template
+ auto destroyCallback()
+ {
+ return registry.on_destroy();
+ }
PLightEnvironment getLightEnvironment() { return lightEnv; }
Gfx::PGraphics getGraphics() const { return graphics; }
entt::registry registry;
diff --git a/src/Engine/System/MeshUpdater.cpp b/src/Engine/System/MeshUpdater.cpp
index d184ad1..5f9a3a4 100644
--- a/src/Engine/System/MeshUpdater.cpp
+++ b/src/Engine/System/MeshUpdater.cpp
@@ -4,18 +4,29 @@ using namespace Seele;
using namespace Seele::System;
MeshUpdater::MeshUpdater(PScene scene)
- : ComponentSystem(scene)
+ : SystemBase(scene)
{
+ scene->view([&](entt::entity id, Component::Mesh& mesh) {
+ meshEntities.add(id);
+ });
+ scene->constructCallback().connect<&MeshUpdater::on_construct>(this);
+ scene->destroyCallback().connect<&MeshUpdater::on_destroy>(this);
}
MeshUpdater::~MeshUpdater()
{
}
-void MeshUpdater::update(Component::Transform& transform, Component::Mesh& meshComp)
+void MeshUpdater::update()
{
- for(const auto& mesh : meshComp.asset->meshes)
- {
- mesh->vertexData->updateMesh(transform, mesh);
- }
+}
+
+void MeshUpdater::on_construct(entt::registry& reg, entt::entity id)
+{
+ meshEntities.add(id);
+}
+
+void MeshUpdater::on_destroy(entt::registry& reg, entt::entity id)
+{
+ meshEntities.remove(id, false);
}
diff --git a/src/Engine/System/MeshUpdater.h b/src/Engine/System/MeshUpdater.h
index c9f6dee..673d0a2 100644
--- a/src/Engine/System/MeshUpdater.h
+++ b/src/Engine/System/MeshUpdater.h
@@ -1,5 +1,5 @@
#pragma once
-#include "ComponentSystem.h"
+#include "SystemBase.h"
#include "Component/Transform.h"
#include "Component/Mesh.h"
@@ -7,13 +7,16 @@ namespace Seele
{
namespace System
{
-class MeshUpdater : public ComponentSystem
+class MeshUpdater : public SystemBase
{
public:
MeshUpdater(PScene scene);
virtual ~MeshUpdater();
- virtual void update(Component::Transform& transform, Component::Mesh& mesh) override;
+ virtual void update() override;
private:
+ Array meshEntities;
+ void on_construct(entt::registry& reg, entt::entity id);
+ void on_destroy(entt::registry& reg, entt::entity id);
};
} // namespace System
} // namespace Seele
\ No newline at end of file