More mesh shading changes
This commit is contained in:
+78
-69
@@ -1,72 +1,81 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||||
<Type Name="Seele::Array<*>">
|
<Type Name="Seele::Array<*>">
|
||||||
<DisplayString>{{ size={arraySize} }}</DisplayString>
|
<DisplayString>{{ size={arraySize} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">arraySize</Item>
|
<Item Name="[size]" ExcludeView="simple">arraySize</Item>
|
||||||
<Item Name="[allocated]" ExcludeView="simple">allocated</Item>
|
<Item Name="[allocated]" ExcludeView="simple">allocated</Item>
|
||||||
<ArrayItems>
|
<ArrayItems>
|
||||||
<Size>arraySize</Size>
|
<Size>arraySize</Size>
|
||||||
<ValuePointer>_data</ValuePointer>
|
<ValuePointer>_data</ValuePointer>
|
||||||
</ArrayItems>
|
</ArrayItems>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
<Type Name="Seele::List<*>">
|
<Type Name="Seele::StaticArray<*,*>">
|
||||||
<DisplayString>{{ size={_size} }}</DisplayString>
|
<DisplayString>{{ size={$T2} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">_size</Item>
|
<ArrayItems>
|
||||||
<LinkedListItems>
|
<Size>$T2</Size>
|
||||||
<Size>_size</Size>
|
<ValuePointer>_data</ValuePointer>
|
||||||
<HeadPointer>root</HeadPointer>
|
</ArrayItems>
|
||||||
<NextPointer>next</NextPointer>
|
</Expand>
|
||||||
<ValueNode>data</ValueNode>
|
</Type>
|
||||||
</LinkedListItems>
|
<Type Name="Seele::List<*>">
|
||||||
</Expand>
|
<DisplayString>{{ size={_size} }}</DisplayString>
|
||||||
</Type>
|
<Expand>
|
||||||
<Type Name="Seele::Pair<*,*>">
|
<Item Name="[size]" ExcludeView="simple">_size</Item>
|
||||||
<DisplayString>[{key}, {value}]</DisplayString>
|
<LinkedListItems>
|
||||||
<Expand>
|
<Size>_size</Size>
|
||||||
<Item Name="[key]">key</Item>
|
<HeadPointer>root</HeadPointer>
|
||||||
<Item Name="[value]">value</Item>
|
<NextPointer>next</NextPointer>
|
||||||
</Expand>
|
<ValueNode>data</ValueNode>
|
||||||
</Type>
|
</LinkedListItems>
|
||||||
<Type Name="Seele::Map<*,*>">
|
</Expand>
|
||||||
<DisplayString>{{ size={_size} }</DisplayString>
|
</Type>
|
||||||
<Expand>
|
<Type Name="Seele::Pair<*,*>">
|
||||||
<Item Name="[size]">_size</Item>
|
<DisplayString>[{key}, {value}]</DisplayString>
|
||||||
<Item Name="[comp]">comp</Item>
|
<Expand>
|
||||||
<ArrayItems>
|
<Item Name="[key]">key</Item>
|
||||||
<Size>_size</Size>
|
<Item Name="[value]">value</Item>
|
||||||
<ValuePointer>nodeContainer._data</ValuePointer>
|
</Expand>
|
||||||
</ArrayItems>
|
</Type>
|
||||||
</Expand>
|
<Type Name="Seele::Map<*,*>">
|
||||||
</Type>
|
<DisplayString>{{ size={_size} }</DisplayString>
|
||||||
<Type Name="Seele::Map<*>::Node">
|
<Expand>
|
||||||
<DisplayString>[{pair}]</DisplayString>
|
<Item Name="[size]">_size</Item>
|
||||||
<Expand>
|
<Item Name="[comp]">comp</Item>
|
||||||
<Item Name="[pair]">pair</Item>
|
<ArrayItems>
|
||||||
<Item Name="[left]">leftChild</Item>
|
<Size>_size</Size>
|
||||||
<Item Name="[right]">rightChild</Item>
|
<ValuePointer>nodeContainer._data</ValuePointer>
|
||||||
</Expand>
|
</ArrayItems>
|
||||||
</Type>
|
</Expand>
|
||||||
<Type Name="Seele::Map<*>::IteratorBase<*>">
|
</Type>
|
||||||
<DisplayString Condition="nodeContainer.arraySize==0">empty</DisplayString>
|
<Type Name="Seele::Map<*>::Node">
|
||||||
<DisplayString>[{nodeContainer._data[node].pair}]</DisplayString>
|
<DisplayString>[{pair}]</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<ExpandedItem>nodeContainer._data[node].pair</ExpandedItem>
|
<Item Name="[pair]">pair</Item>
|
||||||
</Expand>
|
<Item Name="[left]">leftChild</Item>
|
||||||
</Type>
|
<Item Name="[right]">rightChild</Item>
|
||||||
<Type Name="Seele::RefPtr<*>">
|
</Expand>
|
||||||
<DisplayString Condition="object == nullptr">empty</DisplayString>
|
</Type>
|
||||||
<DisplayString>RefPtr {*object}</DisplayString>
|
<Type Name="Seele::Map<*>::IteratorBase<*>">
|
||||||
<Expand>
|
<DisplayString Condition="nodeContainer.arraySize==0">empty</DisplayString>
|
||||||
<ExpandedItem>object</ExpandedItem>
|
<DisplayString>[{nodeContainer._data[node].pair}]</DisplayString>
|
||||||
</Expand>
|
<Expand>
|
||||||
</Type>
|
<ExpandedItem>nodeContainer._data[node].pair</ExpandedItem>
|
||||||
<Type Name="Seele::UniquePtr<*>">
|
</Expand>
|
||||||
<DisplayString>UniquePtr {*handle}</DisplayString>
|
</Type>
|
||||||
<Expand>
|
<Type Name="Seele::RefPtr<*>">
|
||||||
<ExpandedItem>handle</ExpandedItem>
|
<DisplayString Condition="object == nullptr">empty</DisplayString>
|
||||||
</Expand>
|
<DisplayString>RefPtr {*object}</DisplayString>
|
||||||
</Type>
|
<Expand>
|
||||||
|
<ExpandedItem>object</ExpandedItem>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
|
<Type Name="Seele::UniquePtr<*>">
|
||||||
|
<DisplayString>UniquePtr {*handle}</DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<ExpandedItem>handle</ExpandedItem>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
</AutoVisualizer>
|
</AutoVisualizer>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import Common;
|
import Common;
|
||||||
import BRDF;
|
import BRDF;
|
||||||
import Meshlet;
|
import Meshlet;
|
||||||
import Scene;
|
|
||||||
import VertexData;
|
import VertexData;
|
||||||
|
import MaterialParameter;
|
||||||
|
|
||||||
struct MeshPayload
|
struct MeshPayload
|
||||||
{
|
{
|
||||||
@@ -47,14 +47,17 @@ void taskMain(
|
|||||||
MeshData mesh = pScene.meshData[groupID];
|
MeshData mesh = pScene.meshData[groupID];
|
||||||
for(uint i = threadID; i < MAX_MESHLETS_PER_MESH; i += TASK_GROUP_SIZE)
|
for(uint i = threadID; i < MAX_MESHLETS_PER_MESH; i += TASK_GROUP_SIZE)
|
||||||
{
|
{
|
||||||
uint m = mesh.meshletOffset + min(mesh.numMeshlets, i);
|
if(i < mesh.numMeshlets)
|
||||||
MeshletDescription meshlet = pScene.meshlets.meshletInfos[m];
|
|
||||||
//if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum))
|
|
||||||
{
|
{
|
||||||
uint index;
|
uint m = mesh.meshletOffset + i;
|
||||||
InterlockedAdd(head, 1, index);
|
MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||||
p.meshletId[index] = m;
|
//if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum))
|
||||||
p.instanceId[index] = groupID;
|
{
|
||||||
|
uint index;
|
||||||
|
InterlockedAdd(head, 1, index);
|
||||||
|
p.meshletId[index] = m;
|
||||||
|
p.instanceId[index] = groupID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
@@ -71,6 +74,12 @@ struct PrimitiveAttributes
|
|||||||
uint cull: SV_CullPrimitive;
|
uint cull: SV_CullPrimitive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MeshOutput
|
||||||
|
{
|
||||||
|
FragmentParameter parameter : PARAMETER;
|
||||||
|
float4 position_CS : SV_Position;
|
||||||
|
};
|
||||||
|
|
||||||
[numthreads(MESH_GROUP_SIZE, 1, 1)]
|
[numthreads(MESH_GROUP_SIZE, 1, 1)]
|
||||||
[outputtopology("triangle")]
|
[outputtopology("triangle")]
|
||||||
[shader("mesh")]
|
[shader("mesh")]
|
||||||
@@ -78,7 +87,7 @@ void meshMain(
|
|||||||
in uint threadID: SV_GroupIndex,
|
in uint threadID: SV_GroupIndex,
|
||||||
in uint groupID: SV_GroupID,
|
in uint groupID: SV_GroupID,
|
||||||
in payload MeshPayload meshPayload,
|
in payload MeshPayload meshPayload,
|
||||||
out Vertices<VertexAttributes, MAX_VERTICES> vertices,
|
out Vertices<MeshOutput, MAX_VERTICES> vertices,
|
||||||
out Indices<uint3, MAX_PRIMITIVES> indices
|
out Indices<uint3, MAX_PRIMITIVES> indices
|
||||||
){
|
){
|
||||||
InstanceData inst = pScene.instances[meshPayload.instanceId[groupID]];
|
InstanceData inst = pScene.instances[meshPayload.instanceId[groupID]];
|
||||||
@@ -92,10 +101,10 @@ void meshMain(
|
|||||||
InterlockedMax(gs_numVertices, v + 1);
|
InterlockedMax(gs_numVertices, v + 1);
|
||||||
{
|
{
|
||||||
int vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
|
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;
|
const uint primitiveLoops = (MAX_PRIMITIVES + MESH_GROUP_SIZE - 1) / MESH_GROUP_SIZE;
|
||||||
for(uint loop = 0; loop < primitiveLoops; ++loop)
|
for(uint loop = 0; loop < primitiveLoops; ++loop)
|
||||||
{
|
{
|
||||||
@@ -103,15 +112,12 @@ void meshMain(
|
|||||||
p = min(p, m.primitiveCount - 1);
|
p = min(p, m.primitiveCount - 1);
|
||||||
InterlockedMax(gs_numPrimitives, p + 1);
|
InterlockedMax(gs_numPrimitives, p + 1);
|
||||||
{
|
{
|
||||||
uint8_t local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
|
uint32_t local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
|
||||||
uint8_t local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
|
uint32_t local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
|
||||||
uint8_t local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
|
uint32_t local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
|
||||||
uint32_t idx0 = pScene.vertexIndices[m.vertexOffset + local_idx0];
|
gs_indices[p].x = local_idx0;
|
||||||
uint32_t idx1 = pScene.vertexIndices[m.vertexOffset + local_idx1];
|
gs_indices[p].y = local_idx1;
|
||||||
uint32_t idx2 = pScene.vertexIndices[m.vertexOffset + local_idx2];
|
gs_indices[p].z = local_idx2;
|
||||||
gs_indices[p * 3 + 0] = idx0;
|
|
||||||
gs_indices[p * 3 + 1] = idx1;
|
|
||||||
gs_indices[p * 3 + 2] = idx2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
@@ -120,12 +126,16 @@ void meshMain(
|
|||||||
|
|
||||||
uint v = threadID;
|
uint v = threadID;
|
||||||
v = min(v, m.vertexCount - 1);
|
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)
|
if(vertexLoops >= 1)
|
||||||
{
|
{
|
||||||
uint v = threadID + MESH_GROUP_SIZE;
|
uint v = threadID + MESH_GROUP_SIZE;
|
||||||
v = min(v, m.vertexCount - 1);
|
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;
|
uint p = threadID;
|
||||||
@@ -134,19 +144,19 @@ void meshMain(
|
|||||||
|
|
||||||
if(primitiveLoops >= 1)
|
if(primitiveLoops >= 1)
|
||||||
{
|
{
|
||||||
uint p = threadID + MESH_GROUP_SIZE;
|
p += MESH_GROUP_SIZE;
|
||||||
p = min(p, m.primitiveCount - 1);
|
p = min(p, m.primitiveCount - 1);
|
||||||
indices[p] = gs_indices[p];
|
indices[p] = gs_indices[p];
|
||||||
}
|
}
|
||||||
if(primitiveLoops >= 2)
|
if(primitiveLoops >= 2)
|
||||||
{
|
{
|
||||||
uint p = threadID + 2 * MESH_GROUP_SIZE;
|
p += MESH_GROUP_SIZE;
|
||||||
p = min(p, m.primitiveCount - 1);
|
p = min(p, m.primitiveCount - 1);
|
||||||
indices[p] = gs_indices[p];
|
indices[p] = gs_indices[p];
|
||||||
}
|
}
|
||||||
if(primitiveLoops >= 3)
|
if(primitiveLoops >= 3)
|
||||||
{
|
{
|
||||||
uint p = threadID + 3 * MESH_GROUP_SIZE;
|
p += MESH_GROUP_SIZE;
|
||||||
p = min(p, m.primitiveCount - 1);
|
p = min(p, m.primitiveCount - 1);
|
||||||
indices[p] = gs_indices[p];
|
indices[p] = gs_indices[p];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ struct LightingParameter
|
|||||||
// data passed to fragment shader
|
// data passed to fragment shader
|
||||||
struct FragmentParameter
|
struct FragmentParameter
|
||||||
{
|
{
|
||||||
float3 position_TS;
|
float4 position_CS : SV_Position;
|
||||||
float3 viewDir_TS;
|
float3 position_TS : POSITION0;
|
||||||
float3 normal_WS;
|
float3 viewDir_TS : POSITION1;
|
||||||
float3 tangent_WS;
|
float3 normal_WS : NORMAL0;
|
||||||
float3 biTangent_WS;
|
float3 tangent_WS : TANGENT0;
|
||||||
float3 position_WS;
|
float3 biTangent_WS : TANGENT1;
|
||||||
float4 position_CS;
|
float3 position_WS : POSITION2;
|
||||||
float2 texCoords;
|
float2 texCoords : TEXCOORD0;
|
||||||
float3 vertexColor;
|
float3 vertexColor : COLOR0;
|
||||||
MaterialParameter getMaterialParameter()
|
MaterialParameter getMaterialParameter()
|
||||||
{
|
{
|
||||||
MaterialParameter result;
|
MaterialParameter result;
|
||||||
|
|||||||
@@ -194,68 +194,9 @@ 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));
|
||||||
std::set<uint32> uniqueVertices;
|
Meshlet::buildFromIndexBuffer(indices, meshlets);
|
||||||
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();
|
|
||||||
}
|
|
||||||
vertexData->loadMesh(id, meshlets);
|
vertexData->loadMesh(id, meshlets);
|
||||||
|
|
||||||
|
|
||||||
collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
|
collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
|
||||||
|
|
||||||
IndexBufferCreateInfo idxInfo;
|
IndexBufferCreateInfo idxInfo;
|
||||||
|
|||||||
+22
-22
@@ -37,39 +37,39 @@ int main()
|
|||||||
graphics->init(initializer);
|
graphics->init(initializer);
|
||||||
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
|
StaticMeshVertexData* vd = StaticMeshVertexData::getInstance();
|
||||||
vd->init(graphics);
|
vd->init(graphics);
|
||||||
PWindowManager windowManager = new WindowManager();
|
OWindowManager windowManager = new WindowManager();
|
||||||
AssetRegistry::init(sourcePath / "Assets", graphics);
|
AssetRegistry::init(sourcePath / "Assets", graphics);
|
||||||
AssetImporter::init(graphics);
|
AssetImporter::init(graphics);
|
||||||
AssetImporter::importFont(FontImportArgs{
|
AssetImporter::importFont(FontImportArgs{
|
||||||
.filePath = "./fonts/Calibri.ttf",
|
.filePath = "./fonts/Calibri.ttf",
|
||||||
});
|
});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "old_resources/models/arena.fbx",
|
// .filePath = sourcePath / "old_resources/models/arena.fbx",
|
||||||
});
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath = sourcePath / "old_resources/models/train.fbx",
|
.filePath = sourcePath / "old_resources/models/train.fbx",
|
||||||
});
|
});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/bird.fbx",
|
// .filePath= sourcePath / "old_resources/models/bird.fbx",
|
||||||
});
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/cube.fbx",
|
.filePath= sourcePath / "old_resources/models/cube.fbx",
|
||||||
});
|
});
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/flameThrower.fbx",
|
// .filePath= sourcePath / "old_resources/models/flameThrower.fbx",
|
||||||
});
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/player.fbx",
|
// .filePath= sourcePath / "old_resources/models/player.fbx",
|
||||||
});
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/shotgun.fbx",
|
// .filePath= sourcePath / "old_resources/models/shotgun.fbx",
|
||||||
});
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/track.fbx",
|
// .filePath= sourcePath / "old_resources/models/track.fbx",
|
||||||
});
|
// });
|
||||||
AssetImporter::importMesh(MeshImportArgs{
|
//AssetImporter::importMesh(MeshImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/models/zombie.fbx",
|
// .filePath= sourcePath / "old_resources/models/zombie.fbx",
|
||||||
});
|
// });
|
||||||
|
|
||||||
AssetImporter::importTexture(TextureImportArgs{
|
AssetImporter::importTexture(TextureImportArgs{
|
||||||
.filePath= sourcePath / "old_resources/textures/Dirt.png",
|
.filePath= sourcePath / "old_resources/textures/Dirt.png",
|
||||||
|
|||||||
@@ -602,17 +602,18 @@ private:
|
|||||||
// The array is not big enough, so we make a new one
|
// The array is not big enough, so we make a new one
|
||||||
T *newData = allocateArray(newSize);
|
T *newData = allocateArray(newSize);
|
||||||
|
|
||||||
// And move the current elements into that one
|
|
||||||
for(size_type i = 0; i < arraySize; ++i)
|
|
||||||
{
|
|
||||||
newData[i] = std::forward<Type>(_data[i]);
|
|
||||||
}
|
|
||||||
if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>)
|
if constexpr (std::is_integral_v<T> || std::is_floating_point_v<T>)
|
||||||
{
|
{
|
||||||
|
std::memcpy(newData, _data, sizeof(T) * arraySize);
|
||||||
std::memset(&newData[arraySize], 0, sizeof(T) * (newSize - arraySize));
|
std::memset(&newData[arraySize], 0, sizeof(T) * (newSize - arraySize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// And move the current elements into that one
|
||||||
|
for(size_type i = 0; i < arraySize; ++i)
|
||||||
|
{
|
||||||
|
newData[i] = std::forward<Type>(_data[i]);
|
||||||
|
}
|
||||||
// As well as default initialize the others
|
// As well as default initialize the others
|
||||||
for (size_type i = arraySize; i < newSize; ++i)
|
for (size_type i = arraySize; i < newSize; ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,14 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
|
|||||||
lightCullingLayout->create();
|
lightCullingLayout->create();
|
||||||
|
|
||||||
basePassLayout->addDescriptorLayout(INDEX_LIGHT_CULLING, lightCullingLayout);
|
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()
|
BasePass::~BasePass()
|
||||||
@@ -124,6 +131,7 @@ void BasePass::render()
|
|||||||
pipelineInfo.pipelineLayout = std::move(layout);
|
pipelineInfo.pipelineLayout = std::move(layout);
|
||||||
pipelineInfo.renderPass = renderPass;
|
pipelineInfo.renderPass = renderPass;
|
||||||
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL;
|
pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL;
|
||||||
|
pipelineInfo.rasterizationState.lineWidth = 10.f;
|
||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,14 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
|||||||
|
|
||||||
depthPrepassLayout = graphics->createPipelineLayout();
|
depthPrepassLayout = graphics->createPipelineLayout();
|
||||||
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout);
|
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()
|
DepthPrepass::~DepthPrepass()
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer)
|
|||||||
loadNormals(id, nor);
|
loadNormals(id, nor);
|
||||||
loadTangents(id, tan);
|
loadTangents(id, tan);
|
||||||
loadBiTangents(id, bit);
|
loadBiTangents(id, bit);
|
||||||
loadBiTangents(id, col);
|
loadColors(id, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticMeshVertexData::init(Gfx::PGraphics graphics)
|
void StaticMeshVertexData::init(Gfx::PGraphics graphics)
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Component/Mesh.h"
|
#include "Component/Mesh.h"
|
||||||
#include "Graphics/Shader.h"
|
#include "Graphics/Shader.h"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
|
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 16 * 1024;
|
||||||
|
|
||||||
void VertexData::resetMeshData()
|
void VertexData::resetMeshData()
|
||||||
{
|
{
|
||||||
@@ -17,7 +18,6 @@ void VertexData::resetMeshData()
|
|||||||
{
|
{
|
||||||
mat.material->getDescriptorLayout()->reset();
|
mat.material->getDescriptorLayout()->reset();
|
||||||
}
|
}
|
||||||
materialData.clear();
|
|
||||||
if (dirty)
|
if (dirty)
|
||||||
{
|
{
|
||||||
updateBuffers();
|
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();
|
PMaterial mat = mesh->referencedMaterial->getHandle()->getBaseMaterial();
|
||||||
MaterialData& matData = materialData[mat->getName()];
|
MaterialData& matData = materialData[mat->getName()];
|
||||||
@@ -34,15 +34,66 @@ void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh)
|
|||||||
matInstanceData.meshes.add(MeshInstanceData{
|
matInstanceData.meshes.add(MeshInstanceData{
|
||||||
.id = mesh->id,
|
.id = mesh->id,
|
||||||
.instance = InstanceData {
|
.instance = InstanceData {
|
||||||
.transformMatrix = transform.toMatrix(),
|
.transformMatrix = Matrix4(),
|
||||||
},
|
},
|
||||||
.indexBuffer = mesh->indexBuffer,
|
.indexBuffer = mesh->indexBuffer,
|
||||||
});
|
});
|
||||||
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
|
matInstanceData.materialInstance = mesh->referencedMaterial->getHandle();
|
||||||
matInstanceData.materialInstance->updateDescriptor();
|
|
||||||
matInstanceData.numMeshes += meshData[mesh->id].size();
|
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> 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()
|
void VertexData::createDescriptors()
|
||||||
{
|
{
|
||||||
instanceDataLayout->reset();
|
instanceDataLayout->reset();
|
||||||
@@ -50,14 +101,12 @@ void VertexData::createDescriptors()
|
|||||||
{
|
{
|
||||||
for (auto& [_, matInst] : mat.instances)
|
for (auto& [_, matInst] : mat.instances)
|
||||||
{
|
{
|
||||||
Array<InstanceData> instanceData;
|
|
||||||
Array<MeshData> meshes;
|
Array<MeshData> meshes;
|
||||||
for (auto& inst : matInst.meshes)
|
for (auto& inst : matInst.meshes)
|
||||||
{
|
{
|
||||||
inst.meshes = 0;
|
inst.meshes = 0;
|
||||||
for (const auto& mesh : meshData[inst.id])
|
for (const auto& mesh : meshData[inst.id])
|
||||||
{
|
{
|
||||||
instanceData.add(inst.instance);
|
|
||||||
meshes.add(mesh);
|
meshes.add(mesh);
|
||||||
inst.meshes++;
|
inst.meshes++;
|
||||||
}
|
}
|
||||||
@@ -95,6 +144,9 @@ void VertexData::createDescriptors()
|
|||||||
|
|
||||||
void VertexData::loadMesh(MeshId id, Array<Meshlet> loadedMeshlets)
|
void VertexData::loadMesh(MeshId id, 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();
|
meshData[id].clear();
|
||||||
uint32 currentMesh = 0;
|
uint32 currentMesh = 0;
|
||||||
while (currentMesh < loadedMeshlets.size())
|
while (currentMesh < loadedMeshlets.size())
|
||||||
@@ -239,3 +291,69 @@ void Meshlet::load(ArchiveBuffer& buffer)
|
|||||||
Serialization::load(buffer, numVertices);
|
Serialization::load(buffer, numVertices);
|
||||||
Serialization::load(buffer, numPrimitives);
|
Serialization::load(buffer, numPrimitives);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Seele::Meshlet::buildFromIndexBuffer(const Array<uint32>& indices, Array<Meshlet>& meshlets)
|
||||||
|
{
|
||||||
|
std::set<uint32> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ struct MeshId
|
|||||||
{
|
{
|
||||||
return id <=> other.id;
|
return id <=> other.id;
|
||||||
}
|
}
|
||||||
|
bool operator==(const MeshId& other) const
|
||||||
|
{
|
||||||
|
return id == other.id;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct Meshlet
|
struct Meshlet
|
||||||
{
|
{
|
||||||
@@ -26,6 +30,7 @@ struct Meshlet
|
|||||||
uint32 numPrimitives;
|
uint32 numPrimitives;
|
||||||
void save(ArchiveBuffer& buffer) const;
|
void save(ArchiveBuffer& buffer) const;
|
||||||
void load(ArchiveBuffer& buffer);
|
void load(ArchiveBuffer& buffer);
|
||||||
|
static void buildFromIndexBuffer(const Array<uint32>& indices, Array<Meshlet>& meshlets);
|
||||||
};
|
};
|
||||||
class VertexData
|
class VertexData
|
||||||
{
|
{
|
||||||
@@ -47,7 +52,7 @@ public:
|
|||||||
Gfx::OShaderBuffer instanceBuffer;
|
Gfx::OShaderBuffer instanceBuffer;
|
||||||
Gfx::OShaderBuffer meshDataBuffer;
|
Gfx::OShaderBuffer meshDataBuffer;
|
||||||
Gfx::PDescriptorSet descriptorSet;
|
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<MeshInstanceData> meshes;
|
Array<MeshInstanceData> meshes;
|
||||||
};
|
};
|
||||||
struct MaterialData
|
struct MaterialData
|
||||||
@@ -62,7 +67,9 @@ public:
|
|||||||
uint32 indicesOffset;
|
uint32 indicesOffset;
|
||||||
};
|
};
|
||||||
void resetMeshData();
|
void resetMeshData();
|
||||||
void updateMesh(const Component::Transform& transform, PMesh mesh);
|
void addMesh(PMesh mesh);
|
||||||
|
void removeMesh(PMesh mesh);
|
||||||
|
void updateInstances();
|
||||||
void createDescriptors();
|
void createDescriptors();
|
||||||
void loadMesh(MeshId id, Array<Meshlet> meshlets);
|
void loadMesh(MeshId id, Array<Meshlet> meshlets);
|
||||||
MeshId allocateVertexData(uint64 numVertices);
|
MeshId allocateVertexData(uint64 numVertices);
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ OStagingBuffer StagingManager::create(uint64 size)
|
|||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
.size = size,
|
.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,
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||||
.queueFamilyIndexCount = 1,
|
.queueFamilyIndexCount = 1,
|
||||||
.pQueueFamilyIndices = &queueIndex,
|
.pQueueFamilyIndices = &queueIndex,
|
||||||
|
|||||||
@@ -359,11 +359,15 @@ void Graphics::pickPhysicalDevice()
|
|||||||
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
|
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
|
||||||
VkPhysicalDevice bestDevice = VK_NULL_HANDLE;
|
VkPhysicalDevice bestDevice = VK_NULL_HANDLE;
|
||||||
uint32 deviceRating = 0;
|
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)
|
for (auto dev : physicalDevices)
|
||||||
{
|
{
|
||||||
uint32 currentRating = 0;
|
uint32 currentRating = 0;
|
||||||
vkGetPhysicalDeviceProperties(dev, &props);
|
vkGetPhysicalDeviceProperties(dev, &props);
|
||||||
vkGetPhysicalDeviceFeatures(dev, &features);
|
vkGetPhysicalDeviceFeatures2(dev, &features);
|
||||||
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||||
{
|
{
|
||||||
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
|
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
|
||||||
@@ -382,8 +386,9 @@ void Graphics::pickPhysicalDevice()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
physicalDevice = bestDevice;
|
physicalDevice = bestDevice;
|
||||||
|
|
||||||
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
vkGetPhysicalDeviceProperties(physicalDevice, &props);
|
||||||
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
|
vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
|
||||||
if (Gfx::useMeshShading)
|
if (Gfx::useMeshShading)
|
||||||
{
|
{
|
||||||
uint32 count = 0;
|
uint32 count = 0;
|
||||||
@@ -500,31 +505,25 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
|||||||
*currentPriority++ = 1.0f;
|
*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 = {
|
VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
|
||||||
|
.pNext = nullptr,
|
||||||
.taskShader = VK_TRUE,
|
.taskShader = VK_TRUE,
|
||||||
.meshShader = VK_TRUE,
|
.meshShader = VK_TRUE,
|
||||||
};
|
};
|
||||||
if (supportMeshShading())
|
if (supportMeshShading())
|
||||||
{
|
{
|
||||||
descriptorIndexing.pNext = &enabledMeshShaderFeatures;
|
features12.pNext = &enabledMeshShaderFeatures;
|
||||||
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
|
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
VkDeviceCreateInfo deviceInfo = {
|
VkDeviceCreateInfo deviceInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
|
||||||
.pNext = &descriptorIndexing,
|
.pNext = &features12,
|
||||||
.queueCreateInfoCount = (uint32)queueInfos.size(),
|
.queueCreateInfoCount = (uint32)queueInfos.size(),
|
||||||
.pQueueCreateInfos = queueInfos.data(),
|
.pQueueCreateInfos = queueInfos.data(),
|
||||||
.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(),
|
.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(),
|
||||||
.ppEnabledExtensionNames = initializer.deviceExtensions.data(),
|
.ppEnabledExtensionNames = initializer.deviceExtensions.data(),
|
||||||
.pEnabledFeatures = &features,
|
.pEnabledFeatures = &features.features,
|
||||||
};
|
};
|
||||||
|
|
||||||
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
|
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ protected:
|
|||||||
thread_local static OCommandPool transferCommands;
|
thread_local static OCommandPool transferCommands;
|
||||||
thread_local static OCommandPool dedicatedTransferCommands;
|
thread_local static OCommandPool dedicatedTransferCommands;
|
||||||
VkPhysicalDeviceProperties props;
|
VkPhysicalDeviceProperties props;
|
||||||
VkPhysicalDeviceFeatures features;
|
VkPhysicalDeviceFeatures2 features;
|
||||||
|
VkPhysicalDeviceVulkan12Features features12;
|
||||||
VkDebugReportCallbackEXT callback;
|
VkDebugReportCallbackEXT callback;
|
||||||
Map<uint32, OFramebuffer> allocatedFramebuffers;
|
Map<uint32, OFramebuffer> allocatedFramebuffers;
|
||||||
OAllocator allocator;
|
OAllocator allocator;
|
||||||
|
|||||||
@@ -358,7 +358,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
|
|||||||
|
|
||||||
if (graphicsPipelines.contains(hash))
|
if (graphicsPipelines.contains(hash))
|
||||||
{
|
{
|
||||||
std::cout << "Caching pipeline" << std::endl;
|
|
||||||
return graphicsPipelines[hash];
|
return graphicsPipelines[hash];
|
||||||
}
|
}
|
||||||
VkPipeline pipelineHandle;
|
VkPipeline pipelineHandle;
|
||||||
|
|||||||
@@ -257,14 +257,14 @@ void Window::chooseSwapSurfaceFormat()
|
|||||||
|
|
||||||
void Window::chooseSwapPresentMode()
|
void Window::chooseSwapPresentMode()
|
||||||
{
|
{
|
||||||
for (const auto& supportedPresentMode : supportedPresentModes)
|
/*for (const auto& supportedPresentMode : supportedPresentModes)
|
||||||
{
|
{
|
||||||
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
|
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
|
||||||
{
|
{
|
||||||
presentMode = supportedPresentMode;
|
presentMode = supportedPresentMode;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
presentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ void MaterialInstance::setBaseMaterial(PMaterialAsset asset)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
baseMaterial = asset;
|
baseMaterial = asset;
|
||||||
|
updateDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialInstance::save(ArchiveBuffer& buffer) const
|
void MaterialInstance::save(ArchiveBuffer& buffer) const
|
||||||
|
|||||||
@@ -44,6 +44,16 @@ public:
|
|||||||
{
|
{
|
||||||
registry.view<Component...>().each(func);
|
registry.view<Component...>().each(func);
|
||||||
}
|
}
|
||||||
|
template<typename Component>
|
||||||
|
auto constructCallback()
|
||||||
|
{
|
||||||
|
return registry.on_construct<Component>();
|
||||||
|
}
|
||||||
|
template<typename Component>
|
||||||
|
auto destroyCallback()
|
||||||
|
{
|
||||||
|
return registry.on_destroy<Component>();
|
||||||
|
}
|
||||||
PLightEnvironment getLightEnvironment() { return lightEnv; }
|
PLightEnvironment getLightEnvironment() { return lightEnv; }
|
||||||
Gfx::PGraphics getGraphics() const { return graphics; }
|
Gfx::PGraphics getGraphics() const { return graphics; }
|
||||||
entt::registry registry;
|
entt::registry registry;
|
||||||
|
|||||||
@@ -4,18 +4,29 @@ using namespace Seele;
|
|||||||
using namespace Seele::System;
|
using namespace Seele::System;
|
||||||
|
|
||||||
MeshUpdater::MeshUpdater(PScene scene)
|
MeshUpdater::MeshUpdater(PScene scene)
|
||||||
: ComponentSystem<Component::Transform, Component::Mesh>(scene)
|
: SystemBase(scene)
|
||||||
{
|
{
|
||||||
|
scene->view<Component::Mesh>([&](entt::entity id, Component::Mesh& mesh) {
|
||||||
|
meshEntities.add(id);
|
||||||
|
});
|
||||||
|
scene->constructCallback<Component::Mesh>().connect<&MeshUpdater::on_construct>(this);
|
||||||
|
scene->destroyCallback<Component::Mesh>().connect<&MeshUpdater::on_destroy>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
MeshUpdater::~MeshUpdater()
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ComponentSystem.h"
|
#include "SystemBase.h"
|
||||||
#include "Component/Transform.h"
|
#include "Component/Transform.h"
|
||||||
#include "Component/Mesh.h"
|
#include "Component/Mesh.h"
|
||||||
|
|
||||||
@@ -7,13 +7,16 @@ namespace Seele
|
|||||||
{
|
{
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
class MeshUpdater : public ComponentSystem<Component::Transform, Component::Mesh>
|
class MeshUpdater : public SystemBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MeshUpdater(PScene scene);
|
MeshUpdater(PScene scene);
|
||||||
virtual ~MeshUpdater();
|
virtual ~MeshUpdater();
|
||||||
virtual void update(Component::Transform& transform, Component::Mesh& mesh) override;
|
virtual void update() override;
|
||||||
private:
|
private:
|
||||||
|
Array<entt::entity> meshEntities;
|
||||||
|
void on_construct(entt::registry& reg, entt::entity id);
|
||||||
|
void on_destroy(entt::registry& reg, entt::entity id);
|
||||||
};
|
};
|
||||||
} // namespace System
|
} // namespace System
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
Reference in New Issue
Block a user