diff --git a/res/shaders/LegacyBasePass.slang b/res/shaders/LegacyBasePass.slang new file mode 100644 index 0000000..31f85ae --- /dev/null +++ b/res/shaders/LegacyBasePass.slang @@ -0,0 +1,24 @@ +import VertexData; +import StaticMeshVertexData; + +struct InstanceData +{ + float4x4 transformMatrix; +}; + +struct Scene +{ + StructuredBuffer instances; +} + +ParameterBlock scene; + +[shader("vertex")] +StaticMeshVertexAttributes vertexMain( + uint vertexId: SV_VertexID, + uint instanceId: SV_InstanceID, +){ + InstanceData inst = scene.instances[instanceId]; + StaticMeshVertexAttributes attr = vertexData.getAttributes(vertexId, inst.transformMatrix); + return attr; +} \ No newline at end of file diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang new file mode 100644 index 0000000..11b7d94 --- /dev/null +++ b/res/shaders/MeshletBasePass.slang @@ -0,0 +1,152 @@ +import Common; +import BRDF; +import Meshlet; +import Scene; +import StaticMeshVertexData; + +struct MeshPayload +{ + uint instanceId[MAX_MESHLETS_PER_MESH]; + uint meshletId[MAX_MESHLETS_PER_MESH]; +}; + +groupshared MeshPayload p; +groupshared uint head; +groupshared float4x4 localToClip; +groupshared Frustum viewFrustum; + +[numthreads(TASK_GROUP_SIZE, 1, 1)] +[outputtopology("triangle")] +[shader("amplification")] +void taskMain( + uint threadID: SV_GroupIndex, + uint groupID: SV_GroupID +){ + InstanceData instance = scene.instances[groupID]; + if(threadID == 0) + { + head = 0; + localToClip = mul(viewParams.projectionMatrix, mul(viewParams.viewMatrix, instance.transformMatrix)); + // Left + viewFrustum.sides[0].n = float3(1, 0, 0); + viewFrustum.sides[0].d = -1; + // Right + viewFrustum.sides[1].n = float3(-1, 0, 0); + viewFrustum.sides[1].d = 1; + // Top + viewFrustum.sides[2].n = float3(0, -1, 0); + viewFrustum.sides[2].d = 1; + // Bottom + viewFrustum.sides[1].n = float3(0, 1, 0); + viewFrustum.sides[1].d = -1; + // Base + viewFrustum.basePlane.n = float3(0, 0, 1); + viewFrustum.basePlane.d = 0; + } + GroupMemoryBarrierWithGroupSync(); + MeshData mesh = scene.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 = scene.meshlets.meshletInfos[m]; + //if(meshlet.boundingBox.insideFrustum(localToClip, viewFrustum)) + { + uint index; + InterlockedAdd(head, 1, index); + p.meshletId[index] = m; + p.instanceId[index] = groupID; + } + } + GroupMemoryBarrierWithGroupSync(); + DispatchMesh(head, 1, 1, p); +} + +groupshared StaticMeshVertexAttributes gs_vertices[MAX_VERTICES]; +groupshared uint3 gs_indices[MAX_PRIMITIVES]; +groupshared uint gs_numVertices; +groupshared uint gs_numPrimitives; + +struct PrimitiveAttributes +{ + uint cull: SV_CullPrimitive; +}; + +[numthreads(MESH_GROUP_SIZE, 1, 1)] +[outputtopology("triangle")] +[shader("mesh")] +void meshMain( + in uint threadID: SV_GroupIndex, + in uint groupID: SV_GroupID, + in payload MeshPayload meshPayload, + out Vertices vertices, + out Indices indices +){ + InstanceData inst = scene.instances[meshPayload.instanceId[groupID]]; + MeshletDescription m = meshlets.meshletInfos[meshPayload.meshletId[groupID]]; + const uint vertexLoops = (MAX_VERTICES + MESH_GROUP_SIZE - 1) / MESH_GROUP_SIZE; + for(uint loop = 0; loop < vertexLoops; ++loop) + { + uint v = threadID + loop * MESH_GROUP_SIZE; + v = min(v, m.vertexCount - 1); + InterlockedMax(gs_numVertices, v + 1); + { + int vertexIndex = meshlets.vertexIndices[m.vertexOffset + v]; + gs_vertices[v] = vertexData.getAttributes(vertexIndex, inst); + } + } + + const uint primitiveLoops = (MAX_PRIMITIVES + MESH_GROUP_SIZE - 1) / MESH_GROUP_SIZE; + for(uint loop = 0; loop < primitiveLoops; ++loop) + { + uint p = threadID + loop * MESH_GROUP_SIZE; + p = min(p, m.primitiveCount - 1); + InterlockedMax(gs_numPrimitives, p + 1); + { + uint8_t local_idx0 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 0]; + uint8_t local_idx1 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 1]; + uint8_t local_idx2 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 2]; + uint32_t idx0 = meshlets.vertexIndices[m.vertexOffset + local_idx0]; + uint32_t idx1 = meshlets.vertexIndices[m.vertexOffset + local_idx1]; + uint32_t idx2 = meshlets.vertexIndices[m.vertexOffset + local_idx2]; + gs_indices[p * 3 + 0] = idx0; + gs_indices[p * 3 + 1] = idx1; + gs_indices[p * 3 + 2] = idx2; + } + } + GroupMemoryBarrierWithGroupSync(); + SetMeshOutputCounts(gs_numVertices, gs_numPrimitives); + GroupMemoryBarrierWithGroupSync(); + + uint v = threadID; + v = min(v, m.vertexCount - 1); + vertices[v] = gs_vertices[v]; + if(vertexLoops >= 1) + { + uint v = threadID + MESH_GROUP_SIZE; + v = min(v, m.vertexCount - 1); + vertices[v] = gs_vertices[v]; + } + + uint p = threadID; + p = min(p, m.primitiveCount - 1); + indices[p] = gs_indices[p]; + + if(primitiveLoops >= 1) + { + uint p = threadID + 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 = min(p, m.primitiveCount - 1); + indices[p] = gs_indices[p]; + } + if(primitiveLoops >= 3) + { + uint p = threadID + 3 * MESH_GROUP_SIZE; + p = min(p, m.primitiveCount - 1); + indices[p] = gs_indices[p]; + } +} \ No newline at end of file diff --git a/res/shaders/StaticMeshBasePass.slang b/res/shaders/StaticMeshBasePass.slang deleted file mode 100644 index 98713b8..0000000 --- a/res/shaders/StaticMeshBasePass.slang +++ /dev/null @@ -1,93 +0,0 @@ -import Common; -import BRDF; -import Meshlet; -import Scene; -import VertexData; -import StaticMeshVertexData; - -layout(push_constant) -ConstantBuffer meshId; - -struct MeshShaderPayload -{ - uint instanceId; - uint meshletId; -}; - -struct PrimitiveAttributes -{ - uint cull: SV_CullPrimitive; -}; - -groupshared StaticMeshVertexAttributes gs_vertices[MAX_VERTICES]; -groupshared uint3 gs_indices[MAX_PRIMITIVES]; -groupshared uint gs_numVertices; -groupshared uint gs_numPrimitives; - -[numthreads(GROUP_SIZE, 1, 1)] -[shader("amplification")] -void taskMain( - uint3 threadID: SV_GroupIndex, - uint3 groupID: SV_GroupID -){ - -} - -[numthreads(GROUP_SIZE, 1, 1)] -[outputtopology("triangle")] -[shader("mesh")] -void meshMain( - uint3 threadID: SV_GroupIndex, - uint3 groupID: SV_GroupID, - out Vertices vertices, - out Indices indices -){ - MeshShaderPayload p; - InstanceData inst = scene.instances[p.instanceId]; - MeshletDescription m = meshlets.meshletInfos[p.meshletId]; - const uint vertexLoops = (MAX_VERTICES + GROUP_SIZE - 1) / GROUP_SIZE; - for(uint loop = 0; loop < vertexLoops; ++loop) - { - uint v = threadID.x + loop * GROUP_SIZE; - v = min(v, m.vertexCount - 1); - InterlockedMax(gs_numVertices, v + 1); - { - int vertexIndex = meshlets.vertexIndices[m.vertexOffset + v]; - gs_vertices[v] = vertexData.getAttributes(vertexIndex, inst); - } - } - - const uint primitiveLoops = (MAX_PRIMITIVES + GROUP_SIZE - 1) / GROUP_SIZE; - for(uint loop = 0; loop < primitiveLoops; ++loop) - { - uint p = threadID.x + loop * GROUP_SIZE; - p = min(p, m.primitiveCount - 1); - InterlockedMax(gs_numPrimitives, p + 1); - { - uint8_t local_idx0 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 0]; - uint8_t local_idx1 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 1]; - uint8_t local_idx2 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 2]; - uint32_t idx0 = meshlets.vertexIndices[m.vertexOffset + local_idx0]; - uint32_t idx1 = meshlets.vertexIndices[m.vertexOffset + local_idx1]; - uint32_t idx2 = meshlets.vertexIndices[m.vertexOffset + local_idx2]; - gs_indices[p * 3 + 0] = idx0; - gs_indices[p * 3 + 1] = idx1; - gs_indices[p * 3 + 2] = idx2; - } - } - GroupMemoryBarrierWithGroupSync(); - SetMeshOutputCounts(gs_numVertices, gs_numPrimitives); - GroupMemoryBarrierWithGroupSync(); - for(uint loop = 0; loop < vertexLoops; ++loop) - { - uint v = threadID.x + loop * GROUP_SIZE; - v = min(v, m.vertexCount - 1); - vertices[v] = gs_vertices[v]; - } - for(uint loop = 0; loop < primitiveLoops; ++loop) - { - uint p = threadID.x + loop * GROUP_SIZE; - p = min(p, m.primitiveCount - 1); - indices[p] = gs_indices[p]; - } -} \ No newline at end of file diff --git a/res/shaders/lib/AABB.slang b/res/shaders/lib/AABB.slang new file mode 100644 index 0000000..e43456c --- /dev/null +++ b/res/shaders/lib/AABB.slang @@ -0,0 +1,27 @@ +import Common; + +struct AABB +{ + float3 min; + float3 max; + bool insideFrustum(float4x4 transform, Frustum frustum) + { + float3 corners[8]; + corners[0] = mul(transform, float4(min.x, min.y, min.z, 1.0f)).xyz; + corners[1] = mul(transform, float4(min.x, min.y, max.z, 1.0f)).xyz; + corners[2] = mul(transform, float4(min.x, max.y, min.z, 1.0f)).xyz; + corners[3] = mul(transform, float4(min.x, max.y, max.z, 1.0f)).xyz; + corners[4] = mul(transform, float4(max.x, min.y, min.z, 1.0f)).xyz; + corners[5] = mul(transform, float4(max.x, min.y, max.z, 1.0f)).xyz; + corners[6] = mul(transform, float4(max.x, max.y, min.z, 1.0f)).xyz; + corners[7] = mul(transform, float4(max.x, max.y, max.z, 1.0f)).xyz; + for(int i = 0; i < 8; ++i) + { + if(frustum.pointInside(corners[i])) + { + return true; + } + } + return false; + } +}; diff --git a/res/shaders/lib/Common.slang b/res/shaders/lib/Common.slang index f265718..4a06fb3 100644 --- a/res/shaders/lib/Common.slang +++ b/res/shaders/lib/Common.slang @@ -9,7 +9,7 @@ struct ViewParameter float4 cameraPos_WS; float2 screenDimensions; } -//layout(set = INDEX_VIEW_PARAMS, binding = 0, std430) +layout(set = INDEX_VIEW_PARAMS) ParameterBlock viewParams; @@ -31,7 +31,24 @@ struct Plane struct Frustum { - Plane planes[4]; + Plane sides[4]; + Plane basePlane; + bool pointInside(float3 point) + { + if (dot(basePlane.n, point) + basePlane.d < 0) + { + return false; + } + for(int p = 0; p < 4; ++p) + { + float result = dot(sides[p].n, point) + sides[p].d; + if(result < 0) + { + return false; + } + } + return true; + } }; Plane computePlane(float3 p0, float3 p1, float3 p2) { diff --git a/res/shaders/lib/Material.slang b/res/shaders/lib/Material.slang index 77c2c18..d57d7e6 100644 --- a/res/shaders/lib/Material.slang +++ b/res/shaders/lib/Material.slang @@ -8,4 +8,5 @@ interface IMaterial }; +layout(set = INDEX_MATERIAL) ParameterBlock gMaterial; diff --git a/res/shaders/lib/Meshlet.slang b/res/shaders/lib/Meshlet.slang index c389af5..5006e9f 100644 --- a/res/shaders/lib/Meshlet.slang +++ b/res/shaders/lib/Meshlet.slang @@ -1,5 +1,8 @@ +import AABB; + struct MeshletDescription { + AABB boundingBox; uint32_t vertexCount; uint32_t primitiveCount; uint32_t vertexOffset; @@ -14,8 +17,30 @@ struct MeshletData StructuredBuffer vertexIndices; }; +struct MeshData +{ + uint numMeshlets; + uint meshletOffset; +}; + static const uint MAX_VERTICES = 64; static const uint MAX_PRIMITIVES = 126; -static const uint GROUP_SIZE = 32; +static const uint TASK_GROUP_SIZE = 128; +static const uint MESH_GROUP_SIZE = 32; +static const uint MAX_MESHLETS_PER_MESH = 512; + +struct InstanceData +{ + float4x4 transformMatrix; +}; + +struct Scene +{ + StructuredBuffer instances; + StructuredBuffer meshData; + StructuredBuffer meshlets; +}; + +layout(set = INDEX_SCENE_DATA) +ParameterBlock scene; -ParameterBlock meshlets; diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index 7ea2fca..e69de29 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -1,20 +0,0 @@ -struct InstanceData -{ - float4x4 transformMatrix; -}; - -struct MeshData -{ - uint numMeshlets; - uint meshletOffset; - uint numInstances; - uint instanceOffset; -}; - -struct Scene -{ - StructuredBuffer instances; - StructuredBuffer meshData; -}; - -ParameterBlock scene; diff --git a/res/shaders/lib/SkinnedMeshVertexData.slang b/res/shaders/lib/SkinnedMeshVertexData.slang new file mode 100644 index 0000000..bbcb315 --- /dev/null +++ b/res/shaders/lib/SkinnedMeshVertexData.slang @@ -0,0 +1,67 @@ +import VertexData; +import Common; +import Scene; + +struct SkinnedMeshVertexAttributes : VertexAttributes +{ + float4 clipPosition: SV_Position; + float3 worldPosition: POSITION0; + float2 texCoords: TEXCOORD0; + float3 normal: NORMAL0; + float3 tangent: TANGENT0; + float3 biTangent: BITANGENT0; + float3 getWorldPosition() + { + return worldPosition; + } + float2 getTexCoords() + { + return texCoords; + } + float3 getNormal() + { + return normal; + } + float3 getTangent() + { + return tangent; + } + float3 getBiTangent() + { + return biTangent; + } +} + +struct SkinnedMeshVertexData : VertexData +{ + SkinnedMeshVertexAttributes getAttributes(uint index, float4x4 transform) + { + StaticMeshVertexAttributes attr; + float4x4 boneTransform = float4x4(1.0f); + for(int i = 0; i < 4; ++i) + { + boneTransform += bones[boneIndices[i]] * boneWeights[i]; + } + float4 localPos = mul(boneTransform, float4(positions[index], 1)); + float4 worldPos = mul(transform, localPos); + float4 viewPos = mul(viewParams.viewMatrix, worldPos); + float4 clipPos = mul(viewParams.projectionMatrix, viewPos); + attr.clipPosition = clipPos; + attr.worldPosition = worldPos.xyz; + attr.texCoords = texCoords[index]; + attr.normal = normals[index]; + attr.tangent = tangents[index]; + attr.biTangent = biTangents[index]; + return attr; + } + StructuredBuffer positions; + StructuredBuffer texCoords; + StructuredBuffer normals; + StructuredBuffer tangents; + StructuredBuffer biTangents; + StructuredBuffer boneIndices; + StructuredBuffer boneWeights; + StructuredBuffer bones; +} +layout(set = INDEX_VERTEX_DATA) +ParameterBlock vertexData; \ No newline at end of file diff --git a/res/shaders/lib/StaticMeshVertexData.slang b/res/shaders/lib/StaticMeshVertexData.slang index 627ca7e..0cb2685 100644 --- a/res/shaders/lib/StaticMeshVertexData.slang +++ b/res/shaders/lib/StaticMeshVertexData.slang @@ -34,11 +34,11 @@ struct StaticMeshVertexAttributes : VertexAttributes struct StaticMeshVertexData : VertexData { - StaticMeshVertexAttributes getAttributes(uint index, InstanceData inst) + StaticMeshVertexAttributes getAttributes(uint index, float4x4 transform) { StaticMeshVertexAttributes attr; float4 localPos = float4(positions[index], 1); - float4 worldPos = mul(inst.transformMatrix, localPos); + float4 worldPos = mul(transform, localPos); float4 viewPos = mul(viewParams.viewMatrix, worldPos); float4 clipPos = mul(viewParams.projectionMatrix, viewPos); attr.clipPosition = clipPos; @@ -55,4 +55,5 @@ struct StaticMeshVertexData : VertexData StructuredBuffer tangents; StructuredBuffer biTangents; } +layout(set = INDEX_VERTEX_DATA) ParameterBlock vertexData; \ No newline at end of file diff --git a/res/shaders/lib/VertexData.slang b/res/shaders/lib/VertexData.slang index 12c7978..a8d6078 100644 --- a/res/shaders/lib/VertexData.slang +++ b/res/shaders/lib/VertexData.slang @@ -11,5 +11,5 @@ interface VertexAttributes interface VertexData { - VertexAttributes getAttributes(uint index, InstanceData inst); + VertexAttributes getAttributes(uint index, float4x4 transform); }; \ No newline at end of file diff --git a/res/shaders/test.glsl b/res/shaders/test.glsl index c851c7e..51a51d9 100755 --- a/res/shaders/test.glsl +++ b/res/shaders/test.glsl @@ -1,22 +1,23 @@ -#pragma pack_matrix(column_major) -#ifdef SLANG_HLSL_ENABLE_NVAPI -#include "nvHLSLExtns.h" -#endif -#pragma warning(disable: 3557) +#version 450 +#extension GL_EXT_mesh_shader : require +#extension GL_EXT_shader_8bit_storage : require +#extension GL_EXT_shader_explicit_arithmetic_types : require +layout(row_major) uniform; +layout(row_major) buffer; - -#line 1 "lib/Scene.slang" +#line 1 0 struct InstanceData_0 { - matrix transformMatrix_0; + mat4x4 transformMatrix_0; }; -#line 45 "test.slang" -StructuredBuffer scene_instances_0 : register(t0, space3); +#line 45 1 +layout(std430, binding = 0, set = 2) readonly buffer StructuredBuffer_InstanceData_t_0 { + InstanceData_0 _data[]; +} scene_instances_0; - -#line 1 "lib/Meshlet.slang" +#line 1 2 struct MeshletDescription_0 { uint vertexCount_0; @@ -26,130 +27,197 @@ struct MeshletDescription_0 }; -#line 46 "test.slang" -StructuredBuffer meshlets_meshletInfos_0 : register(t0, space2); - - -#line 9 "lib/Meshlet.slang" -StructuredBuffer meshlets_primitiveIndices_0 : register(t1, space2); +#line 46 1 +layout(std430, binding = 0, set = 1) readonly buffer StructuredBuffer_MeshletDescription_t_0 { + MeshletDescription_0 _data[]; +} meshlets_meshletInfos_0; +#line 9 2 +layout(std430, binding = 1, set = 1) readonly buffer StructuredBuffer_uint8_t_0 { + uint8_t _data[]; +} meshlets_primitiveIndices_0; #line 9 -StructuredBuffer meshlets_vertexIndices_0 : register(t2, space2); - - -#line 35 "lib/StaticMeshVertexData.slang" -StructuredBuffer vertexData_positions_0 : register(t0, space4); +layout(std430, binding = 2, set = 1) readonly buffer StructuredBuffer_uint_t_0 { + uint _data[]; +} meshlets_vertexIndices_0; +#line 35 3 +layout(std430, binding = 0, set = 3) readonly buffer StructuredBuffer_float3_t_0 { + vec3 _data[]; +} vertexData_positions_0; #line 35 -StructuredBuffer vertexData_texCoords_0 : register(t1, space4); - +layout(std430, binding = 1, set = 3) readonly buffer StructuredBuffer_float2_t_0 { + vec2 _data[]; +} vertexData_texCoords_0; #line 35 -StructuredBuffer vertexData_normals_0 : register(t2, space4); - +layout(std430, binding = 2, set = 3) readonly buffer StructuredBuffer_float3_t_1 { + vec3 _data[]; +} vertexData_normals_0; #line 35 -StructuredBuffer vertexData_tangents_0 : register(t3, space4); - +layout(std430, binding = 3, set = 3) readonly buffer StructuredBuffer_float3_t_2 { + vec3 _data[]; +} vertexData_tangents_0; #line 35 -StructuredBuffer vertexData_biTangents_0 : register(t4, space4); +layout(std430, binding = 4, set = 3) readonly buffer StructuredBuffer_float3_t_3 { + vec3 _data[]; +} vertexData_biTangents_0; - -#line 5 "lib/Common.slang" +#line 5 4 struct ViewParameter_0 { - matrix viewMatrix_0; - matrix projectionMatrix_0; - float4 cameraPos_WS_0; - float2 screenDimensions_0; + mat4x4 viewMatrix_0; + mat4x4 projectionMatrix_0; + vec4 cameraPos_WS_0; + vec2 screenDimensions_0; }; -cbuffer viewParams_0 : register(b0, space1) +layout(binding = 0) +layout(std140) uniform _S1 { - ViewParameter_0 viewParams_0; -} + mat4x4 viewMatrix_0; + mat4x4 projectionMatrix_0; + vec4 cameraPos_WS_0; + vec2 screenDimensions_0; +}viewParams_0; -#line 24 "test.slang" -static groupshared uint gs_numVertices_0; +#line 1267 5 +out gl_MeshPerVertexEXT +{ + vec4 gl_Position; +} gl_MeshVerticesEXT[64]; -#line 5 "lib/StaticMeshVertexData.slang" +#line 24 1 +shared uint gs_numVertices_0; + + +#line 5 3 struct StaticMeshVertexAttributes_0 { - float4 clipPosition_0 : SV_Position; - float3 worldPosition_0 : POSITION0; - float2 texCoords_0 : TEXCOORD0; - float3 normal_0 : NORMAL0; - float3 tangent_0 : TANGENT0; - float3 biTangent_0 : BITANGENT0; + vec4 clipPosition_0; + vec3 worldPosition_0; + vec2 texCoords_0; + vec3 normal_0; + vec3 tangent_0; + vec3 biTangent_0; }; -#line 22 "test.slang" -static groupshared StaticMeshVertexAttributes_0 gs_vertices_0[int(64)]; +#line 22 1 +shared StaticMeshVertexAttributes_0 gs_vertices_0[64]; -#line 37 "lib/StaticMeshVertexData.slang" -StaticMeshVertexAttributes_0 StaticMeshVertexData_getAttributes_0(StructuredBuffer this_positions_0, StructuredBuffer this_texCoords_0, StructuredBuffer this_normals_0, StructuredBuffer this_tangents_0, StructuredBuffer this_biTangents_0, uint index_0, InstanceData_0 inst_0) +shared uint gs_numPrimitives_0; + + +#line 23 +shared uvec3 gs_indices_0[126]; + + +#line 7910 6 +layout(location = 0) +out vec3 _S2[64]; + + +#line 7910 +layout(location = 1) +out vec2 _S3[64]; + + +#line 7910 +layout(location = 2) +out vec3 _S4[64]; + + +#line 7910 +layout(location = 3) +out vec3 _S5[64]; + + +#line 7910 +layout(location = 4) +out vec3 _S6[64]; + + +#line 7910 +out uvec3 gl_PrimitiveTriangleIndicesEXT[126]; + + +#line 900 7 +StaticMeshVertexAttributes_0 StaticMeshVertexData_getAttributes_0(uint _S7, InstanceData_0 _S8) { - - float4 worldPos_0 = mul(inst_0.transformMatrix_0, float4(this_positions_0.Load(index_0), 1.0)); +#line 41 3 + vec4 worldPos_0 = (((vec4(vertexData_positions_0._data[_S7], 1.0)) * (_S8.transformMatrix_0))); #line 39 StaticMeshVertexAttributes_0 attr_0; #line 44 - attr_0.clipPosition_0 = mul(viewParams_0.projectionMatrix_0, mul(viewParams_0.viewMatrix_0, worldPos_0)); + attr_0.clipPosition_0 = ((((((worldPos_0) * (viewParams_0.viewMatrix_0)))) * (viewParams_0.projectionMatrix_0))); attr_0.worldPosition_0 = worldPos_0.xyz; - attr_0.texCoords_0 = this_texCoords_0.Load(index_0); - attr_0.normal_0 = this_normals_0.Load(index_0); - attr_0.tangent_0 = this_tangents_0.Load(index_0); - attr_0.biTangent_0 = this_biTangents_0.Load(index_0); + attr_0.texCoords_0 = vertexData_texCoords_0._data[_S7]; + attr_0.normal_0 = vertexData_normals_0._data[_S7]; + attr_0.tangent_0 = vertexData_tangents_0._data[_S7]; + attr_0.biTangent_0 = vertexData_biTangents_0._data[_S7]; return attr_0; } -#line 25 "test.slang" -static groupshared uint gs_numPrimitives_0; - - -#line 23 -static groupshared uint3 gs_indices_0[int(126)]; - - -#line 39 -[shader("mesh")][numthreads(32, 1, 1)] -[outputtopology("triangle")] -void meshMain(uint threadID_0 : SV_GROUPINDEX, uint3 groupID_0 : SV_GROUPID, vertices out StaticMeshVertexAttributes_0 vertices_0[int(64)], indices out uint3 indices_0[int(126)]) +#line 39 1 +layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in; +layout(max_vertices = 64) out; +layout(max_primitives = 126) out; +layout(triangles) out; +void main() { - - - InstanceData_0 _S1 = scene_instances_0.Load(threadID_0); - MeshletDescription_0 _S2 = meshlets_meshletInfos_0.Load(groupID_0.x); + InstanceData_0 _S9 = scene_instances_0._data[gl_LocalInvocationIndex]; + MeshletDescription_0 m_0 = meshlets_meshletInfos_0._data[gl_WorkGroupID.x]; #line 51 - uint _S3 = _S2.vertexCount_0 - 1U; + uint _S10 = m_0.vertexCount_0 - 1U; #line 63 - uint _S4 = _S2.primitiveCount_0 - 1U; + uint _S11 = m_0.primitiveCount_0 - 1U; -#line 63 +#line 82 + uint v_0 = min(gl_LocalInvocationIndex, _S10); + + + + uint v_1 = gl_LocalInvocationIndex + 32U; + uint v_2 = min(v_1, _S10); + +#line 92 + uint p_0 = min(gl_LocalInvocationIndex, _S11); + +#line 98 + uint p_1 = min(v_1, _S11); + +#line 104 + uint p_2 = min(gl_LocalInvocationIndex + 64U, _S11); + +#line 110 + uint p_3 = min(gl_LocalInvocationIndex + 96U, _S11); + +#line 110 uint loop_0 = 0U; -#line 63 +#line 110 for(;;) { #line 51 - uint v_0 = min(threadID_0 + loop_0 * 32U, _S3); - InterlockedMax(gs_numVertices_0, v_0 + 1U); + uint v_3 = min(gl_LocalInvocationIndex + loop_0 * 32U, _S10); + atomicMax((gs_numVertices_0), (v_3 + 1U)); - gs_vertices_0[v_0] = StaticMeshVertexData_getAttributes_0(vertexData_positions_0, vertexData_texCoords_0, vertexData_normals_0, vertexData_tangents_0, vertexData_biTangents_0, uint(int(meshlets_vertexIndices_0.Load(_S2.vertexOffset_0 + v_0))), _S1); + gs_vertices_0[v_3] = StaticMeshVertexData_getAttributes_0(uint(int(meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + v_3])), _S9); #line 48 uint loop_1 = loop_0 + 1U; @@ -179,21 +247,21 @@ void meshMain(uint threadID_0 : SV_GROUPINDEX, uint3 groupID_0 : SV_GROUPID, ver { #line 63 - uint p_0 = min(threadID_0 + loop_0 * 32U, _S4); - InterlockedMax(gs_numPrimitives_0, p_0 + 1U); + uint p_4 = min(gl_LocalInvocationIndex + loop_0 * 32U, _S11); + atomicMax((gs_numPrimitives_0), (p_4 + 1U)); - uint _S5 = p_0 * 3U; + uint _S12 = p_4 * 3U; #line 66 - uint _S6 = _S2.primitiveOffset_0 + _S5; + uint _S13 = m_0.primitiveOffset_0 + _S12; - uint idx1_0 = meshlets_vertexIndices_0.Load(_S2.vertexOffset_0 + uint(meshlets_primitiveIndices_0.Load(_S6 + 1U))); - uint idx2_0 = meshlets_vertexIndices_0.Load(_S2.vertexOffset_0 + uint(meshlets_primitiveIndices_0.Load(_S6 + 2U))); - gs_indices_0[_S5] = (uint3)meshlets_vertexIndices_0.Load(_S2.vertexOffset_0 + uint(meshlets_primitiveIndices_0.Load(_S6))); - gs_indices_0[_S5 + 1U] = (uint3)idx1_0; - gs_indices_0[_S5 + 2U] = (uint3)idx2_0; + uint idx1_0 = meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13 + 1U])]; + uint idx2_0 = meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13 + 2U])]; + gs_indices_0[_S12] = uvec3(meshlets_vertexIndices_0._data[m_0.vertexOffset_0 + uint(meshlets_primitiveIndices_0._data[_S13])]); + gs_indices_0[_S12 + 1U] = uvec3(idx1_0); + gs_indices_0[_S12 + 2U] = uvec3(idx2_0); #line 60 uint loop_2 = loop_0 + 1U; @@ -216,11 +284,65 @@ void meshMain(uint threadID_0 : SV_GROUPINDEX, uint3 groupID_0 : SV_GROUPID, ver } #line 77 - GroupMemoryBarrierWithGroupSync(); - SetMeshOutputCounts(gs_numVertices_0, gs_numPrimitives_0); - GroupMemoryBarrierWithGroupSync(); - vertices_0[threadID_0] = gs_vertices_0[threadID_0]; - indices_0[threadID_0] = gs_indices_0[threadID_0]; + barrier(); + SetMeshOutputsEXT(gs_numVertices_0, gs_numPrimitives_0); + barrier(); + + + + StaticMeshVertexAttributes_0 _S14 = gs_vertices_0[v_0]; + +#line 83 + gl_MeshVerticesEXT[v_0].gl_Position = gs_vertices_0[v_0].clipPosition_0; + +#line 83 + _S2[v_0] = _S14.worldPosition_0; + +#line 83 + _S3[v_0] = _S14.texCoords_0; + +#line 83 + _S4[v_0] = _S14.normal_0; + +#line 83 + _S5[v_0] = _S14.tangent_0; + +#line 83 + _S6[v_0] = _S14.biTangent_0; + +#line 88 + StaticMeshVertexAttributes_0 _S15 = gs_vertices_0[v_2]; + +#line 88 + gl_MeshVerticesEXT[v_2].gl_Position = gs_vertices_0[v_2].clipPosition_0; + +#line 88 + _S2[v_2] = _S15.worldPosition_0; + +#line 88 + _S3[v_2] = _S15.texCoords_0; + +#line 88 + _S4[v_2] = _S15.normal_0; + +#line 88 + _S5[v_2] = _S15.tangent_0; + +#line 88 + _S6[v_2] = _S15.biTangent_0; + +#line 93 + gl_PrimitiveTriangleIndicesEXT[p_0] = gs_indices_0[p_0]; + +#line 99 + gl_PrimitiveTriangleIndicesEXT[p_1] = gs_indices_0[p_1]; + +#line 105 + gl_PrimitiveTriangleIndicesEXT[p_2] = gs_indices_0[p_2]; + +#line 111 + gl_PrimitiveTriangleIndicesEXT[p_3] = gs_indices_0[p_3]; + return; } diff --git a/res/shaders/test.slang b/res/shaders/test.slang index 776abaf..9db3b68 100644 --- a/res/shaders/test.slang +++ b/res/shaders/test.slang @@ -1,90 +1,63 @@ -import Common; -import BRDF; -import Meshlet; -import Scene; -import VertexData; -import StaticMeshVertexData; -layout(push_constant) -ConstantBuffer meshId; - -struct MeshShaderPayload +struct MeshPayload { - uint instanceId; - uint meshletId; + int exponent; }; -struct PrimitiveAttributes -{ - uint cull: SV_CullPrimitive; -}; +groupshared MeshPayload payload; -groupshared StaticMeshVertexAttributes gs_vertices[MAX_VERTICES]; -groupshared uint3 gs_indices[MAX_PRIMITIVES]; -groupshared uint gs_numVertices; -groupshared uint gs_numPrimitives; - -[numthreads(GROUP_SIZE, 1, 1)] -[shader("amplification")] +[numthreads(1, 1, 1)] +[outputtopology("triangle")] void taskMain( uint3 threadID: SV_GroupIndex, uint3 groupID: SV_GroupID ){ - + DispatchMesh(1,1,1,payload); } -[numthreads(GROUP_SIZE, 1, 1)] + + +const static float2 positions[3] = { + float2(0.0, -0.5), + float2(0.5, 0.5), + float2(-0.5, 0.5) +}; + +const static float3 colors[3] = { + float3(1.0, 1.0, 0.0), + float3(0.0, 1.0, 1.0), + float3(1.0, 0.0, 1.0) +}; +struct Vertex +{ + float4 pos : SV_Position; + float3 color : Color; + int index : Index; + int value : Value; +}; + +const static uint MAX_VERTS = 12; +const static uint MAX_PRIMS = 4; + [outputtopology("triangle")] [shader("mesh")] +[numthreads(12, 1, 1)] void meshMain( - uint threadID: SV_GroupIndex, - uint3 groupID: SV_GroupID, - out Vertices vertices, - out Indices indices -){ - InstanceData inst = scene.instances[threadID]; - MeshletDescription m = meshlets.meshletInfos[groupID.x]; - const uint vertexLoops = (MAX_VERTICES + GROUP_SIZE - 1) / GROUP_SIZE; - for(uint loop = 0; loop < vertexLoops; ++loop) - { - uint v = threadID + loop * GROUP_SIZE; - v = min(v, m.vertexCount - 1); - InterlockedMax(gs_numVertices, v + 1); - { - int vertexIndex = meshlets.vertexIndices[m.vertexOffset + v]; - gs_vertices[v] = vertexData.getAttributes(vertexIndex, inst); - } - } + in uint tig : SV_GroupIndex, + in payload MeshPayload meshPayload, + out Vertices verts, + out Indices triangles) +{ + const uint numVertices = 12; + const uint numPrimitives = 4; + SetMeshOutputCounts(numVertices, numPrimitives); - const uint primitiveLoops = (MAX_PRIMITIVES + GROUP_SIZE - 1) / GROUP_SIZE; - for(uint loop = 0; loop < primitiveLoops; ++loop) - { - uint p = threadID + loop * GROUP_SIZE; - p = min(p, m.primitiveCount - 1); - InterlockedMax(gs_numPrimitives, p + 1); - { - uint8_t local_idx0 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 0]; - uint8_t local_idx1 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 1]; - uint8_t local_idx2 = meshlets.primitiveIndices[m.primitiveOffset + (p * 3) + 2]; - uint32_t idx0 = meshlets.vertexIndices[m.vertexOffset + local_idx0]; - uint32_t idx1 = meshlets.vertexIndices[m.vertexOffset + local_idx1]; - uint32_t idx2 = meshlets.vertexIndices[m.vertexOffset + local_idx2]; - gs_indices[p * 3 + 0] = idx0; - gs_indices[p * 3 + 1] = idx1; - gs_indices[p * 3 + 2] = idx2; - } - } - GroupMemoryBarrierWithGroupSync(); - SetMeshOutputCounts(gs_numVertices, gs_numPrimitives); - GroupMemoryBarrierWithGroupSync(); - for(uint loop1 = 0; loop1 < vertexLoops; ++loop1) - { - uint v = threadID + loop1 * GROUP_SIZE; - vertices[v] = gs_vertices[v]; - } - for(uint loop2 = 0; loop2 < primitiveLoops; ++loop2) - { - uint p = threadID + loop2 * GROUP_SIZE; - indices[p] = gs_indices[p]; - } + if(tig < numVertices) + { + const int tri = tig / 3; + verts[tig] = {float4(positions[tig % 3], 0, 1), colors[tig % 3], tri, int(pow(tri, meshPayload.exponent))}; + } + + if(tig < numPrimitives) + triangles[tig] = tig * 3 + uint3(0,1,2); } \ No newline at end of file diff --git a/src/Engine/Asset/MeshAsset.h b/src/Engine/Asset/MeshAsset.h index ac5cb27..8890390 100644 --- a/src/Engine/Asset/MeshAsset.h +++ b/src/Engine/Asset/MeshAsset.h @@ -15,8 +15,6 @@ public: virtual ~MeshAsset(); virtual void save(ArchiveBuffer& buffer) const override; virtual void load(ArchiveBuffer& buffer) override; - void addMesh(PMesh mesh); - const Array getMeshes(); //Workaround while no editor Array meshes; Component::Collider physicsMesh; diff --git a/src/Engine/Component/CMakeLists.txt b/src/Engine/Component/CMakeLists.txt index 1c8b398..4731b91 100644 --- a/src/Engine/Component/CMakeLists.txt +++ b/src/Engine/Component/CMakeLists.txt @@ -9,6 +9,7 @@ target_sources(Engine Component.h DirectionalLight.h KeyboardInput.h + Mesh.h MeshCollider.h PointLight.h RigidBody.h @@ -16,7 +17,6 @@ target_sources(Engine ShapeBase.cpp Skybox.h SphereCollider.h - StaticMesh.h Transform.h Transform.cpp) @@ -32,10 +32,10 @@ target_sources(Engine DirectionalLight.h KeyboardInput.h MeshCollider.h + Mesh.h PointLight.h RigidBody.h ShapeBase.h Skybox.h SphereCollider.h - StaticMesh.h Transform.h) \ No newline at end of file diff --git a/src/Engine/Component/Mesh.h b/src/Engine/Component/Mesh.h new file mode 100644 index 0000000..406cdd5 --- /dev/null +++ b/src/Engine/Component/Mesh.h @@ -0,0 +1,18 @@ +#pragma once +#include "Asset/MeshAsset.h" +#include "Graphics/VertexData.h" +#include "Graphics/TopologyData.h" +#include "Material/MaterialInstance.h" + +namespace Seele +{ +namespace Component +{ +struct Mesh +{ + VertexData* vertexData; + MeshId id; + PMaterialInstance instance; +}; +} // namespace Component +} // namespace Seele diff --git a/src/Engine/Component/StaticMesh.h b/src/Engine/Component/StaticMesh.h deleted file mode 100644 index 7a2be45..0000000 --- a/src/Engine/Component/StaticMesh.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include "Asset/MeshAsset.h" - -namespace Seele -{ -namespace Component -{ -struct StaticMesh -{ - StaticMesh() {} - StaticMesh(PMeshAsset mesh) : mesh(mesh) {} - PMeshAsset mesh; -}; -} // namespace Component -} // namespace Seele diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index 18cbc86..c88e677 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -10,8 +10,6 @@ target_sources(Engine Graphics.cpp Mesh.h Mesh.cpp - MeshBatch.h - MeshBatch.cpp ShaderCompiler.h ShaderCompiler.cpp StaticMeshVertexData.h @@ -28,7 +26,6 @@ target_sources(Engine GraphicsEnums.h Graphics.h Mesh.h - MeshBatch.h ShaderCompiler.h StaticMeshVertexData.h VertexData.h) diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 7a3fbd3..3e64849 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -2,7 +2,6 @@ #include "MinimalEngine.h" #include "GraphicsResources.h" #include "Containers/Array.h" -#include "VertexShaderInput.h" #include "ShaderCompiler.h" namespace Seele diff --git a/src/Engine/Graphics/GraphicsEnums.h b/src/Engine/Graphics/GraphicsEnums.h index 55bdde5..d7e100b 100644 --- a/src/Engine/Graphics/GraphicsEnums.h +++ b/src/Engine/Graphics/GraphicsEnums.h @@ -165,24 +165,10 @@ namespace Gfx { static constexpr bool useAsyncCompute = true; static constexpr bool waitIdleOnSubmit = true; +static constexpr bool useMeshShading = true; static constexpr uint32 numFramesBuffered = 8; double getCurrentFrameDelta(); -enum class MaterialShadingModel -{ - Unlit, - DefaultLit, - Subsurface, - PreintegratedSkin, - ClearCoat, - SubsurfaceProfile, - TwoSidedFoliage, - Hair, - Cloth, - Eye, - Max -}; - enum class RenderPassType : uint8 { DepthPrepass, @@ -196,14 +182,6 @@ enum class QueueType TRANSFER = 3, DEDICATED_TRANSFER = 4 }; -enum class VertexAttribute -{ - POSITION, - TEXCOORD, - NORMAL, - TANGENT, - BITANGENT -}; typedef uint32_t SeFlags; typedef uint32_t SeBool32; diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index 996a328..1747907 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -644,8 +644,8 @@ public: virtual void bindVertexBuffer(const Array& streams) = 0; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0; - virtual void draw(const MeshBatchElement& data) = 0; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; + virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ); std::string name; }; DEFINE_REF(RenderCommand) diff --git a/src/Engine/Graphics/IndexBufferTopologyData.cpp b/src/Engine/Graphics/IndexBufferTopologyData.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/Engine/Graphics/IndexBufferTopologyData.h b/src/Engine/Graphics/IndexBufferTopologyData.h deleted file mode 100644 index 1d850a1..0000000 --- a/src/Engine/Graphics/IndexBufferTopologyData.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "TopologyData.h" - -namespace Seele -{ -class IndexBufferTopologyData : public TopologyData -{ -public: - IndexBufferTopologyData(); - virtual ~IndexBufferTopologyData(); -private: - Gfx::PIndexBuffer indices; -}; -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Mesh.h b/src/Engine/Graphics/Mesh.h index 9df58ff..ea73a83 100644 --- a/src/Engine/Graphics/Mesh.h +++ b/src/Engine/Graphics/Mesh.h @@ -1,20 +1,19 @@ #pragma once #include "GraphicsResources.h" -#include "Asset/MaterialAsset.h" +#include "Asset/MaterialInstanceAsset.h" +#include "VertexData.h" namespace Seele { -DECLARE_REF(TopologyData) -DECLARE_REF(VertexData) class Mesh { public: Mesh(); ~Mesh(); - PTopologyData meshlets; - PVertexData vertexData; - PMaterialAsset referencedMaterial; + VertexData* vertexData; + MeshId id; + PMaterialInstanceAsset referencedMaterial; private: }; DEFINE_REF(Mesh) diff --git a/src/Engine/Graphics/MeshBatch.cpp b/src/Engine/Graphics/MeshBatch.cpp deleted file mode 100644 index d4db156..0000000 --- a/src/Engine/Graphics/MeshBatch.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "MeshBatch.h" -#include "GraphicsResources.h" -#include "VertexShaderInput.h" -#include "Material/MaterialInterface.h" -#include "Graphics/Graphics.h" - -using namespace Seele; - -MeshBatchElement::MeshBatchElement() - : indexBuffer(nullptr) - , firstIndex(0) - , numPrimitives(0) - , numInstances(1) - , baseVertexIndex(0) - , minVertexIndex(0) - , maxVertexIndex(0) - , indirectArgsBuffer(nullptr) -{} -MeshBatch::MeshBatch() - : elements() - , useReverseCulling(false) - , isBackfaceCullingDisabled(false) - , isCastingShadow(true) - , useWireframe(false) - , topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) - , vertexInput(nullptr) - , material(nullptr) -{ -} \ No newline at end of file diff --git a/src/Engine/Graphics/MeshBatch.h b/src/Engine/Graphics/MeshBatch.h deleted file mode 100644 index 6a676ef..0000000 --- a/src/Engine/Graphics/MeshBatch.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -#include "GraphicsEnums.h" -#include "Containers/Array.h" - -namespace Seele -{ -DECLARE_REF(VertexShaderInput) -DECLARE_REF(MaterialInterface) -DECLARE_NAME_REF(Gfx, VertexBuffer) -DECLARE_NAME_REF(Gfx, IndexBuffer) -DECLARE_NAME_REF(Gfx, UniformBuffer) -struct MeshBatchElement -{ -public: - Gfx::PIndexBuffer indexBuffer; - - uint32 sceneDataIndex; - uint32 firstIndex; - uint32 numPrimitives; - - uint32 numInstances; - uint32 baseVertexIndex; - uint32 minVertexIndex; - uint32 maxVertexIndex; - - uint8 isInstanced : 1; - Gfx::PVertexBuffer indirectArgsBuffer; - MeshBatchElement(); -}; -struct MeshBatch -{ - Array elements; - - uint8 useReverseCulling : 1; - uint8 isBackfaceCullingDisabled : 1; - uint8 isCastingShadow : 1; - uint8 useWireframe : 1; - - Gfx::SePrimitiveTopology topology; - - PVertexShaderInput vertexInput; - - PMaterialInterface material; - - MeshBatch(); - MeshBatch(const MeshBatch& other) = default; - MeshBatch(MeshBatch&& other) = default; - MeshBatch& operator=(const MeshBatch& other) = default; - MeshBatch& operator=(MeshBatch&& other) = default; -}; -} // namespace Seele diff --git a/src/Engine/Graphics/MeshletTopologyData.cpp b/src/Engine/Graphics/MeshletTopologyData.cpp deleted file mode 100644 index 0aa7441..0000000 --- a/src/Engine/Graphics/MeshletTopologyData.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "MeshletTopologyData.h" \ No newline at end of file diff --git a/src/Engine/Graphics/MeshletTopologyData.h b/src/Engine/Graphics/MeshletTopologyData.h deleted file mode 100644 index 8b3a79e..0000000 --- a/src/Engine/Graphics/MeshletTopologyData.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "TopologyData.h" - -namespace Seele -{ -class MeshletTopologyData : public TopologyData -{ -public: -private: -}; -} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 8298675..50fd9bd 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -2,6 +2,7 @@ #include "Graphics/Graphics.h" #include "Window/Window.h" #include "Component/Camera.h" +#include "Component/Mesh.h" #include "Actor/CameraActor.h" #include "Math/Vector.h" #include "RenderGraph.h" @@ -9,69 +10,8 @@ using namespace Seele; -BasePassMeshProcessor::BasePassMeshProcessor(Gfx::PGraphics graphics) - : MeshProcessor(graphics) -// , translucentBasePass(translucentBasePass) - //, cachedPrimitiveIndex(0) -{ -} - -BasePassMeshProcessor::~BasePassMeshProcessor() -{ -} - -void BasePassMeshProcessor::processMeshBatch( - const MeshBatch& batch, - Gfx::PViewport target, - Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout baseLayout, - Gfx::PDescriptorLayout primitiveLayout, - Array descriptorSets, - int32 /*staticMeshId*/) -{ - PMaterialInterface material = batch.material; - //const Gfx::MaterialShadingModel shadingModel = material->getShadingModel(); - - const PVertexShaderInput vertexInput = batch.vertexInput; - - const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType()); - if(collection == nullptr) - { - material->createShaders(graphics, Gfx::RenderPassType::BasePass, vertexInput->getType()); - collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType()); - } - assert(collection != nullptr); - - Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); - renderCommand->setViewport(target); - - Gfx::PPipelineLayout pipelineLayout = graphics->createPipelineLayout(baseLayout); - pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout()); - pipelineLayout->create(); - Gfx::PDescriptorSet materialSet = material->createDescriptorSet(); - descriptorSets[BasePass::INDEX_MATERIAL] = materialSet; - for(uint32 i = 0; i < batch.elements.size(); ++i) - { - buildMeshDrawCommand(batch, - renderPass, - pipelineLayout, - renderCommand, - descriptorSets, - collection->vertexShader, - collection->controlShader, - collection->evalutionShader, - collection->geometryShader, - collection->fragmentShader, - false); - } - std::scoped_lock lock(commandLock); - renderCommands.add(renderCommand); - //co_return; -} - -BasePass::BasePass(Gfx::PGraphics graphics) - : RenderPass(graphics) - , processor(new BasePassMeshProcessor(graphics)) +BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) + : RenderPass(graphics, scene) , descriptorSets(4) { UniformBufferCreateInfo uniformInitializer; @@ -80,11 +20,11 @@ BasePass::BasePass(Gfx::PGraphics graphics) lightLayout = graphics->createDescriptorLayout("LightLayout"); // Directional Lights - lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - // Point Lights + lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + // Point Lights lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - lightLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + lightLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); // Light Index List lightLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); // Light Grid @@ -103,25 +43,32 @@ BasePass::BasePass(Gfx::PGraphics graphics) basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); - primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout"); - primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - primitiveLayout->create(); - basePassLayout->addDescriptorLayout(INDEX_SCENE_DATA, primitiveLayout); - basePassLayout->addPushConstants(Gfx::SePushConstantRange{ - .stageFlags = (Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT), - .offset = 0, - .size = sizeof(uint32), - }); + sceneLayout = graphics->createDescriptorLayout("SceneLayout"); + sceneLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + sceneLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + sceneLayout->create(); + basePassLayout->addDescriptorLayout(INDEX_SCENE_DATA, sceneLayout); + //basePassLayout->addPushConstants(Gfx::SePushConstantRange{ + // .stageFlags = (Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT), + // .offset = 0, + // .size = sizeof(uint32), + //}); } BasePass::~BasePass() -{ +{ +} + +void BasePass::readScene() +{ + Array instances; + scene->view([] + (const Component::Transform& transform, const Component::Mesh& mesh) { + }); } void BasePass::beginFrame(const Component::Camera& cam) { - processor->clearCommands(); - primitiveLayout->reset(); BulkResourceData uniformUpdate; viewParams.viewMatrix = cam.getViewMatrix(); @@ -134,7 +81,7 @@ void BasePass::beginFrame(const Component::Camera& cam) viewLayout->reset(); lightLayout->reset(); - descriptorSets[INDEX_SCENE_DATA] = primitiveLayout->allocateDescriptorSet(); + descriptorSets[INDEX_SCENE_DATA] = sceneLayout->allocateDescriptorSet(); descriptorSets[INDEX_SCENE_DATA]->updateBuffer(0, passData.sceneDataBuffer); descriptorSets[INDEX_SCENE_DATA]->writeChanges(); descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet(); diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 1214526..4ad19f9 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -1,44 +1,16 @@ #pragma once #include "MinimalEngine.h" -#include "MeshProcessor.h" #include "RenderPass.h" namespace Seele { -class BasePassMeshProcessor : public MeshProcessor -{ -public: - BasePassMeshProcessor(Gfx::PGraphics graphics); - virtual ~BasePassMeshProcessor(); - - virtual void processMeshBatch( - const MeshBatch& batch, - Gfx::PViewport target, - Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout pipelineLayout, - Gfx::PDescriptorLayout primitiveLayout, - Array descriptorSets, - int32 staticMeshId = -1) override; -private: - //Array cachedPrimitiveSets; - //uint8 translucentBasePass; - //uint32 cachedPrimitiveIndex; -}; -DEFINE_REF(BasePassMeshProcessor) DECLARE_REF(CameraActor) -struct BasePassData -{ - Array staticDrawList; - Gfx::PShaderBuffer sceneDataBuffer; - LightEnv lightEnv; -}; -class BasePass : public RenderPass +class BasePass : public RenderPass { public: - BasePass(Gfx::PGraphics graphics); - BasePass(BasePass&& other) = default; + BasePass(Gfx::PGraphics graphics, PScene scene); virtual ~BasePass(); - BasePass& operator=(BasePass&& other) = default; + virtual void readScene() override; virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; virtual void endFrame() override; @@ -48,7 +20,6 @@ public: private: Gfx::PRenderTargetAttachment colorAttachment; Gfx::PTexture2D depthBuffer; - UPBasePassMeshProcessor processor; Array descriptorSets; PCameraActor source; @@ -66,9 +37,7 @@ private: static constexpr uint32 INDEX_MATERIAL = 2; // Set 3: primitive scene data static constexpr uint32 INDEX_SCENE_DATA = 3; - Gfx::PDescriptorLayout primitiveLayout; - Gfx::PUniformBuffer primitiveUniformBuffer; - friend class BasePassMeshProcessor; + Gfx::PDescriptorLayout sceneLayout; }; DEFINE_REF(BasePass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index ea4bf3d..8a20ec3 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -8,8 +8,6 @@ target_sources(Engine DepthPrepass.cpp LightCullingPass.h LightCullingPass.cpp - MeshProcessor.h - MeshProcessor.cpp RenderGraph.h RenderGraphResources.h RenderGraphResources.cpp @@ -28,7 +26,6 @@ target_sources(Engine DebugPass.h DepthPrepass.h LightCullingPass.h - MeshProcessor.h RenderGraph.h RenderGraphResources.h RenderPass.h diff --git a/src/Engine/Graphics/RenderPass/DebugPass.h b/src/Engine/Graphics/RenderPass/DebugPass.h index bf7ef5e..6911bfb 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.h +++ b/src/Engine/Graphics/RenderPass/DebugPass.h @@ -9,11 +9,7 @@ namespace Seele DECLARE_REF(CameraActor) DECLARE_REF(Scene) DECLARE_REF(Viewport) -struct DebugPassData -{ - Array vertices; -}; -class DebugPass : public RenderPass +class DebugPass : public RenderPass { public: DebugPass(Gfx::PGraphics graphics); diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 9c8e0ca..1c50c79 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -2,77 +2,16 @@ #include "Graphics/Graphics.h" #include "Window/Window.h" #include "Component/Camera.h" +#include "Component/Mesh.h" #include "Actor/CameraActor.h" #include "Math/Vector.h" #include "RenderGraph.h" -#include "Material/MaterialInterface.h" using namespace Seele; -DepthPrepassMeshProcessor::DepthPrepassMeshProcessor(Gfx::PGraphics graphics) - : MeshProcessor(graphics) -{ -} - -DepthPrepassMeshProcessor::~DepthPrepassMeshProcessor() -{ -} - -void DepthPrepassMeshProcessor::processMeshBatch( - const MeshBatch& batch, - Gfx::PViewport target, - Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout baseLayout, - Gfx::PDescriptorLayout primitiveLayout, - Array descriptorSets, - int32 /*staticMeshId*/) -{ - //std::cout << "Depth void started" << std::endl; - PMaterialInterface material = batch.material; - //const Gfx::MaterialShadingModel shadingModel = material->getShadingModel(); - - const PVertexShaderInput vertexInput = batch.vertexInput; - - const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType()); - if (collection == nullptr) - { - material->createShaders(graphics, Gfx::RenderPassType::DepthPrepass, vertexInput->getType()); - collection = material->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType()); - } - assert(collection != nullptr); - - Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); - renderCommand->setViewport(target); - Gfx::PPipelineLayout pipelineLayout = graphics->createPipelineLayout(baseLayout); - pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getDescriptorLayout()); - pipelineLayout->create(); - Gfx::PDescriptorSet materialSet = material->createDescriptorSet(); - descriptorSets[DepthPrepass::INDEX_MATERIAL] = materialSet; - for(uint32 i = 0; i < batch.elements.size(); ++i) - { - buildMeshDrawCommand(batch, -// primitiveComponent, - renderPass, - pipelineLayout, - renderCommand, - descriptorSets, - collection->vertexShader, - collection->controlShader, - collection->evalutionShader, - collection->geometryShader, - collection->fragmentShader, - true); - } - std::scoped_lock lock(commandLock); - renderCommands.add(renderCommand); - //std::cout << "Finished depth job" << std::endl; - //co_return; -} - -DepthPrepass::DepthPrepass(Gfx::PGraphics graphics) - : RenderPass(graphics) - , processor(new DepthPrepassMeshProcessor(graphics)) - , descriptorSets(3) +DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) + : RenderPass(graphics, scene) + , descriptorSets(4) { UniformBufferCreateInfo uniformInitializer; @@ -86,16 +25,6 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics) viewParamBuffer = graphics->createUniformBuffer(uniformInitializer); viewLayout->create(); depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); - - primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout"); - primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - primitiveLayout->create(); - depthPrepassLayout->addDescriptorLayout(INDEX_SCENE_DATA, primitiveLayout); - depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{ - .stageFlags = (Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT), - .offset = 0, - .size = sizeof(uint32), - }); } DepthPrepass::~DepthPrepass() @@ -104,8 +33,6 @@ DepthPrepass::~DepthPrepass() void DepthPrepass::beginFrame(const Component::Camera& cam) { - processor->clearCommands(); - primitiveLayout->reset(); BulkResourceData uniformUpdate; viewParams.viewMatrix = cam.getViewMatrix(); @@ -116,12 +43,10 @@ void DepthPrepass::beginFrame(const Component::Camera& cam) uniformUpdate.data = (uint8*)&viewParams; viewParamBuffer->updateContents(uniformUpdate); viewLayout->reset(); - descriptorSets[INDEX_SCENE_DATA] = primitiveLayout->allocateDescriptorSet(); - descriptorSets[INDEX_SCENE_DATA]->updateBuffer(0, passData.sceneDataBuffer); - descriptorSets[INDEX_SCENE_DATA]->writeChanges(); descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet(); descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); + //std::cout << "DepthPrepass beginFrame()" << std::endl; //co_return; } @@ -133,11 +58,39 @@ void DepthPrepass::render() Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS); graphics->beginRenderPass(renderPass); - for (const auto& meshBatch : passData.staticDrawList) + for (VertexData* vertexData : VertexData::getList()) { - processor->processMeshBatch(meshBatch, viewport, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets); + const auto& materials = vertexData->getMaterialData(); + for (const auto& [_, materialData] : materials) + { + // Create Pipeline(Material, VertexData) + // Descriptors: + // ViewData => global, static + // Material => per material + // VertexData => per meshtype + // SceneData => per topology + Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender"); + Gfx::PPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout); + layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); + layout->addDescriptorLayout(INDEX_VERTEX_DATA, vertexData->getVertexDataLayout()); + layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout()); + layout->create(); + + GraphicsPipelineCreateInfo pipelineInfo; + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + command->bindPipeline(pipeline); + + vertexData->bindBuffers(command); + descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet(); + for (const auto&[_, instance]: materialData.instances) + { + descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); + descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; + command->bindDescriptor(descriptorSets); + command->dispatch(instance.numMeshes, 1, 1); + } + } } - graphics->executeCommands(processor->getRenderCommands()); graphics->endRenderPass(); //std::cout << "DepthPrepass render()" << std::endl; //co_return; @@ -175,5 +128,6 @@ void DepthPrepass::modifyRenderPassMacros(Map& defines { defines["INDEX_VIEW_PARAMS"] = "0"; defines["INDEX_MATERIAL"] = "1"; - defines["INDEX_SCENE_DATA"] = "2"; + defines["INDEX_VERTEX_DATA"] = "2"; + defines["INDEX_SCENE_DATA"] = "3"; } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index 8eda67c..ba10578 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -1,40 +1,14 @@ #pragma once #include "MinimalEngine.h" -#include "MeshProcessor.h" #include "RenderPass.h" namespace Seele { -class DepthPrepassMeshProcessor : public MeshProcessor +class DepthPrepass : public RenderPass { public: - DepthPrepassMeshProcessor(Gfx::PGraphics graphics); - virtual ~DepthPrepassMeshProcessor(); - - virtual void processMeshBatch( - const MeshBatch& batch, - Gfx::PViewport target, - Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout pipelineLayout, - Gfx::PDescriptorLayout primitiveLayout, - Array descriptorSets, - int32 staticMeshId = -1) override; - -private: -}; -DEFINE_REF(DepthPrepassMeshProcessor) -struct DepthPrepassData -{ - Array staticDrawList; - Gfx::PShaderBuffer sceneDataBuffer; -}; -class DepthPrepass : public RenderPass -{ -public: - DepthPrepass(Gfx::PGraphics graphics); - DepthPrepass(DepthPrepass&& other) = default; + DepthPrepass(Gfx::PGraphics graphics, PScene scene); ~DepthPrepass(); - DepthPrepass& operator=(DepthPrepass& other) = default; virtual void beginFrame(const Component::Camera& cam) override; virtual void render() override; virtual void endFrame() override; @@ -44,9 +18,9 @@ public: private: Gfx::PRenderTargetAttachment depthAttachment; Gfx::PTexture2D depthBuffer; - UPDepthPrepassMeshProcessor processor; - + Array descriptorSets; + Gfx::PPipelineLayout depthPrepassLayout; // Set 0: viewParameter static constexpr uint32 INDEX_VIEW_PARAMS = 0; @@ -54,11 +28,11 @@ private: Gfx::PUniformBuffer viewParamBuffer; // Set 1: materials, generated static constexpr uint32 INDEX_MATERIAL = 1; - // Set 2: primitive scene data - static constexpr uint32 INDEX_SCENE_DATA = 2; - Gfx::PDescriptorLayout primitiveLayout; - Gfx::PUniformBuffer primitiveUniformBuffer; - friend class DepthPrepassMeshProcessor; + // Set 2: vertices, from VertexData + static constexpr uint32 INDEX_VERTEX_DATA = 2; + // Set 3: mesh data, either index buffer or meshlet data + static constexpr uint32 INDEX_SCENE_DATA = 3; + Gfx::PDescriptorLayout sceneDataLayout; }; DEFINE_REF(DepthPrepass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index f841bd9..08cc886 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -12,7 +12,7 @@ struct LightCullingPassData { LightEnv lightEnv; }; -class LightCullingPass : public RenderPass +class LightCullingPass : public RenderPass { public: LightCullingPass(Gfx::PGraphics graphics); diff --git a/src/Engine/Graphics/RenderPass/MeshProcessor.cpp b/src/Engine/Graphics/RenderPass/MeshProcessor.cpp deleted file mode 100644 index ad5f24e..0000000 --- a/src/Engine/Graphics/RenderPass/MeshProcessor.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "MeshProcessor.h" -#include "Graphics/Graphics.h" -#include "Graphics/VertexShaderInput.h" -#include "Graphics/Vulkan/VulkanGraphicsResources.h" - -using namespace Seele; - -MeshProcessor::MeshProcessor(Gfx::PGraphics graphics) - : graphics(graphics) -{ - -} - -MeshProcessor::~MeshProcessor() -{ -} - -void MeshProcessor::buildMeshDrawCommand( - const MeshBatch& meshBatch, -// const PPrimitiveComponent primitiveComponent, - const Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout pipelineLayout, - Gfx::PRenderCommand drawCommand, - const Array& descriptors, - Gfx::PVertexShader vertexShader, - Gfx::PControlShader controlShader, - Gfx::PEvaluationShader evaluationShader, - Gfx::PGeometryShader geometryShader, - Gfx::PFragmentShader fragmentShader, - bool positionOnly) -{ - const PVertexShaderInput vertexInput = meshBatch.vertexInput; - - GraphicsPipelineCreateInfo pipelineInitializer; - pipelineInitializer.topology = meshBatch.topology; - pipelineInitializer.vertexShader = vertexShader; - pipelineInitializer.controlShader = controlShader; - pipelineInitializer.evalShader = evaluationShader; - pipelineInitializer.geometryShader = geometryShader; - pipelineInitializer.fragmentShader = fragmentShader; - pipelineInitializer.renderPass = renderPass; - pipelineInitializer.pipelineLayout = pipelineLayout; - - VertexInputStreamArray vertexStreams; - if(positionOnly) - { - vertexInput->getPositionOnlyStream(vertexStreams); - pipelineInitializer.vertexDeclaration = vertexInput->getPositionDeclaration(); - } - else - { - vertexInput->getStreams(vertexStreams); - pipelineInitializer.vertexDeclaration = vertexInput->getDeclaration(); - } - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInitializer); - drawCommand->bindPipeline(pipeline); - drawCommand->bindVertexBuffer(vertexStreams); - drawCommand->bindDescriptor(descriptors); - for(const auto& element : meshBatch.elements) - { - drawCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(uint32), &element.sceneDataIndex); - if(element.indexBuffer != nullptr) - { - drawCommand->bindIndexBuffer(element.indexBuffer); - drawCommand->draw(element); - } - else - { - drawCommand->draw(vertexStreams[0].vertexBuffer->getNumVertices(), 1, 0, 0); - } - } -} - -Array MeshProcessor::getRenderCommands() -{ - return renderCommands; -} - -void MeshProcessor::clearCommands() -{ - renderCommands.clear(); -} diff --git a/src/Engine/Graphics/RenderPass/MeshProcessor.h b/src/Engine/Graphics/RenderPass/MeshProcessor.h deleted file mode 100644 index 041b76c..0000000 --- a/src/Engine/Graphics/RenderPass/MeshProcessor.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "MinimalEngine.h" -#include "Scene/Scene.h" -#include "Graphics/GraphicsResources.h" -#include "Graphics/MeshBatch.h" - -namespace Seele -{ -class MeshProcessor -{ -public: - MeshProcessor(Gfx::PGraphics graphics); - virtual ~MeshProcessor(); - Array getRenderCommands(); - void clearCommands(); -protected: - PScene scene; - Gfx::PGraphics graphics; - virtual void processMeshBatch( - const MeshBatch& batch, - Gfx::PViewport target, - Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout pipelineLayout, - Gfx::PDescriptorLayout primitiveLayout, - Array descriptorSets, - int32 staticMeshId = -1) = 0; - void buildMeshDrawCommand( - const MeshBatch& meshBatch, -// const PPrimitiveComponent primitiveComponent, - const Gfx::PRenderPass renderPass, - Gfx::PPipelineLayout pipelineLayout, - Gfx::PRenderCommand drawCommand, - const Array& descriptors, - Gfx::PVertexShader vertexShader, - Gfx::PControlShader controlShader, - Gfx::PEvaluationShader evaluationShader, - Gfx::PGeometryShader geometryShader, - Gfx::PFragmentShader fragmentShader, - bool positionOnly); - std::mutex commandLock; - Array renderCommands; -}; -} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h index c820051..631ff49 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.h +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -3,24 +3,25 @@ #include "Math/Math.h" #include "RenderGraphResources.h" #include "Component/Camera.h" +#include "Graphics/TopologyData.h" +#include "Scene/Scene.h" +#include "Material/MaterialInstance.h" +#include "Graphics/VertexData.h" namespace Seele { DECLARE_NAME_REF(Gfx, Viewport) DECLARE_NAME_REF(Gfx, Graphics) DECLARE_NAME_REF(Gfx, RenderPass) -template class RenderPass { public: - RenderPass(Gfx::PGraphics graphics) + RenderPass(Gfx::PGraphics graphics, PScene scene) : graphics(graphics) + , scene(scene) {} virtual ~RenderPass() {} - void updateViewFrame(RenderPassDataType viewFrame) { - passData = std::move(viewFrame); - } virtual void beginFrame(const Component::Camera& cam) = 0; virtual void render() = 0; virtual void endFrame() = 0; @@ -41,13 +42,26 @@ protected: Vector2 screenDimensions; Vector2 pad0; } viewParams; + struct DrawListId + { + DrawListId(PMaterialInstance mat, PVertexData vertex) + { + id = mat->getBaseMaterial()->getName(); + } + std::strong_ordering operator<=>(const DrawListId& other) const + { + return id <=> other.id; + } + std::string id; + }; + Map drawList; PRenderGraphResources resources; - RenderPassDataType passData; Gfx::PRenderPass renderPass; Gfx::PGraphics graphics; Gfx::PViewport viewport; + PScene scene; }; -template -concept RenderPassType = std::derived_from>; +template +concept RenderPassType = std::derived_from; } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h index 3203b0f..bbb7e43 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h @@ -8,11 +8,7 @@ namespace Seele DECLARE_REF(CameraActor) DECLARE_REF(Scene) DECLARE_REF(Viewport) -struct SkyboxPassData -{ - Component::Skybox skybox; -}; -class SkyboxRenderPass : public RenderPass +class SkyboxRenderPass : public RenderPass { public: SkyboxRenderPass(Gfx::PGraphics graphics); diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h index f39dbef..aff3bda 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ b/src/Engine/Graphics/RenderPass/TextPass.h @@ -17,12 +17,7 @@ struct TextRender Vector2 position; float scale; }; -struct TextPassData -{ - Array texts; -}; - -class TextPass : public RenderPass +class TextPass : public RenderPass { public: TextPass(Gfx::PGraphics graphics); diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index c74d087..dee4fc4 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -8,7 +8,5 @@ public: StaticMeshVertexData(); virtual ~StaticMeshVertexData(); private: - Gfx::PShaderBuffer texCoords; - Gfx::PShaderBuffer normals; }; } \ No newline at end of file diff --git a/src/Engine/Graphics/TopologyData.h b/src/Engine/Graphics/TopologyData.h index a35944d..87e6ec6 100644 --- a/src/Engine/Graphics/TopologyData.h +++ b/src/Engine/Graphics/TopologyData.h @@ -1,5 +1,6 @@ #pragma once #include "GraphicsResources.h" +#include "VertexData.h" namespace Seele { @@ -9,6 +10,8 @@ public: TopologyData(); virtual ~TopologyData(); virtual void bind() = 0; -private: +protected: + VertexData* vertexData; }; +DEFINE_REF(TopologyData) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index e69de29..0b194ee 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -0,0 +1,95 @@ +#include "VertexData.h" +#include "Material/Material.h" +#include "Graphics/Graphics.h" + +using namespace Seele; + +void VertexData::resetMeshData() +{ + materialData.clear(); +} + +void VertexData::updateMesh(const Component::Transform& transform, const Component::Mesh& mesh) +{ + PMaterial mat = mesh.instance->getBaseMaterial(); + MaterialData& matData = materialData[mat->getName()]; + MaterialInstanceData& matInstanceData = matData.instances[mesh.instance->getId()]; + matInstanceData.meshes.add(MeshInstanceData{ + .id = mesh.id, + .instance = InstanceData { + .transformMatrix = transform.toMatrix(), + } + }); +} + +void VertexData::createDescriptors() +{ + for (const auto& [_, mat] : materialData) + { + for (auto& [_, matInst] : mat.instances) + { + Array instanceData; + Array meshes; + for (const auto& inst : matInst.meshes) + { + for (const auto& mesh : meshData[inst.id]) + { + instanceData.add(inst.instance); + meshes.add(mesh); + } + } + Gfx::PShaderBuffer instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .resourceData = { + .size = sizeof(InstanceData) * instanceData.size(), + .data = (uint8*)instanceData.data(), + }, + .stride = sizeof(InstanceData) + }); + Gfx::PShaderBuffer meshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .resourceData = { + .size = sizeof(MeshData) * meshes.size(), + .data = (uint8*)meshes.data(), + }, + .stride = sizeof(MeshData) + }); + matInst.descriptorSet = instanceDataLayout->allocateDescriptorSet(); + matInst.descriptorSet->updateBuffer(0, instanceBuffer); + if (Gfx::useMeshShading) + { + matInst.descriptorSet->updateBuffer(1, meshDataBuffer); + matInst.descriptorSet->updateBuffer(2, meshletBuffer); + } + matInst.descriptorSet->writeChanges(); + matInst.numMeshes = meshes.size(); + } + } +} + +List vertexDataList; + +List VertexData::getList() +{ + return vertexDataList; +} + +VertexData::VertexData(Gfx::PGraphics graphics) + : graphics(graphics) +{ + instanceDataLayout = graphics->createDescriptorLayout("VertexDataInstanceLayout"); + instanceDataLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + if (Gfx::useMeshShading) + { + // meshData + instanceDataLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + // meshletData + instanceDataLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); + meshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .resourceData = { + .size = sizeof(MeshletData), + .data = nullptr, + }, + .bDynamic = true, + }); + } + instanceDataLayout->create(); +} \ No newline at end of file diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 3c0ff6f..95dd72d 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -1,13 +1,80 @@ #pragma once #include "GraphicsResources.h" +#include "Material/MaterialInstance.h" +#include "Component/Mesh.h" +#include "Component/Transform.h" namespace Seele { +struct MeshId +{ + uint64 id; +}; class VertexData { public: -private: - Gfx::PShaderBuffer positions; + struct InstanceData + { + Matrix4 transformMatrix; + }; + struct MeshInstanceData + { + MeshId id; + InstanceData instance; + }; + struct MaterialInstanceData + { + PMaterialInstance materialInstance; + Gfx::PDescriptorSet descriptorSet; + uint32_t numMeshes; // not necessarily equal to meshes.size() if a MeshId has multiple meshes + Array meshes; + }; + struct MaterialData + { + PMaterial material; + Map instances; + }; + struct MeshData + { + uint32 numMeshlets; + uint32 meshletOffset; + }; + void resetMeshData(); + void updateMesh(const Component::Transform& transform, const Component::Mesh& mesh); + void createDescriptors(); + virtual void bindBuffers(Gfx::PRenderCommand command) = 0; + virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; + virtual Gfx::PDescriptorSet getVertexDataSet() = 0; + virtual Gfx::PDescriptorLayout getInstanceDataLayout() = 0; + virtual std::string getTypeName() const = 0; + const Map& getMaterialData() const { return materialData; } + const Array& getMeshData(MeshId id) { return meshData[id]; } + static List getList(); +protected: + struct MeshletAABB + { + Vector min; + float pad0; + Vector max; + float pad1; + }; + struct MeshletData + { + MeshletAABB boundingBox; + uint32_t vertexCount; + uint32_t primiticeCount; + uint32_t vertexOffset; + uint32_t primitiveOffset; + }; + Map materialData; + Map> meshData; + Array meshlets; + Gfx::PDescriptorLayout instanceDataLayout; + Gfx::PGraphics graphics; + // for mesh shading + Gfx::PShaderBuffer meshletBuffer; + // for legacy pipeline + Gfx::PIndexBuffer indexBuffer; + VertexData(Gfx::PGraphics graphics); }; -DEFINE_REF(VertexData) } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp index 004554a..1d5f9af 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.cpp @@ -304,18 +304,18 @@ void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStag vkCmdPushConstants(handle, layout.cast()->getHandle(), stage, offset, size, data); } -void RenderCommand::draw(const MeshBatchElement& data) -{ - assert(threadId == std::this_thread::get_id()); - vkCmdDrawIndexed(handle, static_cast(data.indexBuffer->getNumIndices()), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0); -} - void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) { assert(threadId == std::this_thread::get_id()); vkCmdDraw(handle, vertexCount, instanceCount, firstVertex, firstInstance); } +void RenderCommand::dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) +{ + assert(threadId == std::this_thread::get_id()); + vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ); +} + ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics) , owner(cmdPool) diff --git a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h index 9515e12..0fefc8b 100644 --- a/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h +++ b/src/Engine/Graphics/Vulkan/VulkanCommandBuffer.h @@ -90,8 +90,8 @@ public: virtual void bindVertexBuffer(const Array& streams) override; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override; virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override; - virtual void draw(const MeshBatchElement& data) override; virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override; + virtual void dispatch(uint32 groupX, uint32 groupY, uint32 groupZ) override; private: PGraphicsPipeline pipeline; bool ready; diff --git a/src/Engine/Material/CMakeLists.txt b/src/Engine/Material/CMakeLists.txt index 484dad9..e41237d 100644 --- a/src/Engine/Material/CMakeLists.txt +++ b/src/Engine/Material/CMakeLists.txt @@ -4,8 +4,8 @@ target_sources(Engine Material.cpp MaterialInstance.h MaterialInstance.cpp - MaterialInterface.h - MaterialInterface.cpp + + ShaderExpression.h ShaderExpression.cpp) @@ -14,6 +14,5 @@ target_sources(Engine FILES Material.h MaterialInstance.h - MaterialInterface.h ShaderExpression.h) diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 8dd326d..3bb7757 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -1,13 +1,10 @@ #include "Material.h" #include "Window/WindowManager.h" #include "MaterialInstance.h" -#include "Graphics/VertexShaderInput.h" #include "Graphics/Graphics.h" using namespace Seele; -Gfx::ShaderMap Material::shaderMap; -std::mutex Material::shaderMapLock; Material::Material(Gfx::PGraphics graphics, Array parameter, @@ -17,11 +14,15 @@ Material::Material(Gfx::PGraphics graphics, std::string materialName, Array expressions, MaterialNode brdf) - : MaterialInterface(graphics, parameter, uniformDataSize, uniformBinding) + : graphics(graphics) + , parameters(parameter) + , uniformDataSize(uniformDataSize) + , uniformBinding(uniformBinding) , layout(layout) , materialName(materialName) , codeExpressions(expressions) , brdf(brdf) + , instanceId(0) { } @@ -129,19 +130,3 @@ void Material::compile() codeStream << "\t}\n"; codeStream << "};\n"; } - -const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const -{ - Gfx::ShaderPermutation permutation; - permutation.passType = renderPass; - std::string vertexInputName = vertexInput->getName(); - std::strncpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName)); - std::strncpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName)); - return shaderMap.findShaders(Gfx::PermutationId(permutation)); -} - -Gfx::ShaderCollection& Material::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput) -{ - std::scoped_lock l(shaderMapLock); - return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false); -} diff --git a/src/Engine/Material/Material.h b/src/Engine/Material/Material.h index d60dc14..11ca147 100644 --- a/src/Engine/Material/Material.h +++ b/src/Engine/Material/Material.h @@ -1,13 +1,13 @@ #pragma once -#include "MaterialInterface.h" +#include "ShaderExpression.h" +#include "Graphics/GraphicsResources.h" namespace Seele { DECLARE_REF(MaterialInstance) -class Material : public MaterialInterface +class Material { public: - Material() {} Material(Gfx::PGraphics graphics, Array parameter, Gfx::PDescriptorLayout layout, @@ -16,30 +16,27 @@ public: std::string materialName, Array expressions, MaterialNode brdf); - virtual ~Material(); - virtual Gfx::PDescriptorSet createDescriptorSet(); - virtual Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; } - virtual const std::string& getName() { return materialName; } + ~Material(); + Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; } + PMaterialInstance instantiate(); + const std::string& getName() { return materialName; } - virtual void save(ArchiveBuffer& buffer) const; - virtual void load(ArchiveBuffer& buffer); + void save(ArchiveBuffer& buffer) const; + void load(ArchiveBuffer& buffer); void compile(); - virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const; - virtual Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput); private: - static Gfx::ShaderMap shaderMap; - static std::mutex shaderMapLock; - + Gfx::PGraphics graphics; + std::string brdfName; + uint32 uniformDataSize; + uint32 uniformBinding; + uint64 instanceId; Gfx::PDescriptorLayout layout; std::string materialName; Array codeExpressions; + Array parameters; MaterialNode brdf; - // With draw-indirect, we batch vertex data into big vertex buffers - // Gfx::PVertexDataManager vertexData; - - friend class MaterialInstance; }; DEFINE_REF(Material) diff --git a/src/Engine/Material/MaterialInstance.cpp b/src/Engine/Material/MaterialInstance.cpp index 886f85b..434853a 100644 --- a/src/Engine/Material/MaterialInstance.cpp +++ b/src/Engine/Material/MaterialInstance.cpp @@ -4,52 +4,20 @@ using namespace Seele; -MaterialInstance::MaterialInstance(Gfx::PGraphics graphics, PMaterial baseMaterial) - : MaterialInterface(graphics, baseMaterial->parameters, baseMaterial->uniformDataSize, baseMaterial->uniformBinding) - , baseMaterial(baseMaterial) +MaterialInstance::MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array params, uint32 uniformBinding, uint32 uniformSize) + : id(id), graphics(graphics), baseMaterial(baseMaterial), descriptor(descriptor), parameters(params), uniformBinding(uniformBinding) { + uniformBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ + .resourceData = { + .size = uniformSize, + }, + .bDynamic = true, + } + ); + uniformData.resize(uniformSize); } MaterialInstance::~MaterialInstance() { -} - -Gfx::PDescriptorSet MaterialInstance::createDescriptorSet() -{ - Gfx::PDescriptorSet descriptorSet = baseMaterial->layout->allocateDescriptorSet(); - BulkResourceData uniformUpdate; - uniformUpdate.size = uniformDataSize; - uniformUpdate.data = (uint8*)uniformData.data(); - for(auto param : parameters) - { - param->updateDescriptorSet(descriptorSet, uniformData.data()); - } - if(uniformUpdate.size != 0) - { - uniformBuffer->updateContents(uniformUpdate); - descriptorSet->updateBuffer(uniformBinding, uniformBuffer); - } - descriptorSet->writeChanges(); - return descriptorSet; -} - -Gfx::PDescriptorLayout MaterialInstance::getDescriptorLayout() const -{ - return baseMaterial->getDescriptorLayout(); -} - -const std::string& MaterialInstance::getName() -{ - return baseMaterial->getName(); -} - -const Gfx::ShaderCollection* Seele::MaterialInstance::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const -{ - return baseMaterial->getShaders(renderPass, vertexInput); -} - -Gfx::ShaderCollection& Seele::MaterialInstance::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput) -{ - return baseMaterial->createShaders(graphics, renderPass, vertexInput); -} +} \ No newline at end of file diff --git a/src/Engine/Material/MaterialInstance.h b/src/Engine/Material/MaterialInstance.h index 09c5fa0..efee411 100644 --- a/src/Engine/Material/MaterialInstance.h +++ b/src/Engine/Material/MaterialInstance.h @@ -1,24 +1,26 @@ #pragma once -#include "MaterialInterface.h" +#include "Material.h" namespace Seele { -DECLARE_REF(Material) -class MaterialInstance : public MaterialInterface +class MaterialInstance { public: - MaterialInstance(Gfx::PGraphics graphics, PMaterial baseMaterial); - virtual ~MaterialInstance(); - virtual Gfx::PDescriptorSet createDescriptorSet(); - virtual Gfx::PDescriptorLayout getDescriptorLayout() const; - - // The name of the generated material shader, opposed to the name of the .asset file - virtual const std::string& getName(); - virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const; - virtual Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput); - + MaterialInstance(uint64 id, Gfx::PGraphics graphics, PMaterial baseMaterial, Gfx::PDescriptorSet descriptor, Array params, uint32 uniformBinding, uint32 uniformSize); + ~MaterialInstance(); + void updateDescriptor(); + Gfx::PDescriptorSet getDescriptorSet() const; + PMaterial getBaseMaterial() const { return baseMaterial; } + uint64 getId() const { return id; } private: + Gfx::PGraphics graphics; + Array uniformData; + uint32 uniformBinding; + Gfx::PUniformBuffer uniformBuffer; + Array parameters; + Gfx::PDescriptorSet descriptor; PMaterial baseMaterial; + uint64 id; }; DEFINE_REF(MaterialInstance) } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Material/MaterialInterface.cpp b/src/Engine/Material/MaterialInterface.cpp deleted file mode 100644 index 73b1fbe..0000000 --- a/src/Engine/Material/MaterialInterface.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "MaterialInterface.h" -#include "Window/WindowManager.h" -#include "Graphics/Graphics.h" - -using namespace Seele; - -MaterialInterface::MaterialInterface(Gfx::PGraphics graphics, Array parameter, uint32 uniformDataSize, uint32 uniformBinding) - : graphics(graphics) - , parameters(parameter) - , uniformDataSize(uniformDataSize) - , uniformBinding(uniformBinding) -{ - if(uniformDataSize != 0) - { - uniformData.resize(uniformDataSize); - UniformBufferCreateInfo uniformInitializer = { - .resourceData = { - .size = uniformDataSize, - .data = nullptr, - } - }; - uniformBuffer = graphics->createUniformBuffer(uniformInitializer); - } -} - -MaterialInterface::~MaterialInterface() -{ -} - - -PShaderParameter MaterialInterface::getParameter(const std::string& name) -{ - for (const auto& param : parameters) - { - if(param->name.compare(name) == 0) - { - return param; - } - } - return nullptr; -} - -void MaterialInterface::save(ArchiveBuffer& buffer) const -{ - Serialization::save(buffer, uniformDataSize); - Serialization::save(buffer, uniformBinding); - uint64 length = parameters.size(); - Serialization::save(buffer, length); - for (const auto& param : parameters) - { - Serialization::save(buffer, param); - } -} - -void MaterialInterface::load(ArchiveBuffer& buffer) -{ - graphics = buffer.getGraphics(); - Serialization::load(buffer, uniformDataSize); - Serialization::load(buffer, uniformBinding); - - if (uniformDataSize != 0) - { - uniformData.resize(uniformDataSize); - UniformBufferCreateInfo uniformInitializer = { - .resourceData = { - .size = uniformDataSize, - .data = nullptr, - } - }; - uniformBuffer = graphics->createUniformBuffer(uniformInitializer); - } - uint64 length; - Serialization::load(buffer, length); - parameters.resize(length); - for (auto& param : parameters) - { - Serialization::load(buffer, param); - } -} diff --git a/src/Engine/Material/MaterialInterface.h b/src/Engine/Material/MaterialInterface.h deleted file mode 100644 index a77b876..0000000 --- a/src/Engine/Material/MaterialInterface.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "ShaderExpression.h" -#include "Graphics/GraphicsResources.h" - -namespace Seele -{ -DECLARE_NAME_REF(Gfx, DescriptorLayout) -DECLARE_NAME_REF(Gfx, UniformBuffer) -class MaterialInterface -{ -public: - MaterialInterface() {} - MaterialInterface(Gfx::PGraphics graphics, Array parameter, uint32 uniformDataSize, uint32 uniformBinding); - virtual ~MaterialInterface(); - PShaderParameter getParameter(const std::string& name); - virtual Gfx::PDescriptorSet createDescriptorSet() = 0; - virtual Gfx::PDescriptorLayout getDescriptorLayout() const = 0; - - virtual void save(ArchiveBuffer& buffer) const; - virtual void load(ArchiveBuffer& buffer); - - // The name of the generated material shader, opposed to the name of the .asset file - virtual const std::string& getName() = 0; - virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const = 0; - virtual Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput) = 0; -protected: - Gfx::PGraphics graphics; - std::string brdfName; - Array parameters; - Gfx::PUniformBuffer uniformBuffer; - uint32 uniformDataSize; - Array uniformData; - int32 uniformBinding; -}; -DEFINE_REF(MaterialInterface) -} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index cb538fb..64c2a1b 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -16,7 +16,6 @@ Scene::Scene(Gfx::PGraphics graphics) : graphics(graphics) , physics(registry) { - ShaderBufferCreateInfo structInfo = { .resourceData = { .size = sizeof(Component::DirectionalLight) * MAX_DIRECTIONAL_LIGHTS, @@ -50,59 +49,6 @@ void Scene::update(float deltaTime) physics.update(deltaTime); } -Array Scene::getStaticMeshes() -{ - Array result; - auto view = registry.view(); - uint32 sceneDataIndex = 0; - sceneData.clear(); - for(auto&& [entity, mesh, transform] : view.each()) - { - sceneData.add(PrimitiveSceneData { - .localToWorld = transform.toMatrix(), - .worldToLocal = glm::inverse(transform.toMatrix()), - .actorLocation = Vector4(transform.getPosition(), 1.0f) - }); - for(auto& m : mesh.mesh->meshes) - { - auto& batch = result.add(); - batch.material = m->referencedMaterial->getMaterial(); - batch.isBackfaceCullingDisabled = false; - batch.isCastingShadow = true; - batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - batch.useReverseCulling = false; - batch.useWireframe = false; - batch.vertexInput = m->vertexInput; - MeshBatchElement batchElement; - batchElement.baseVertexIndex = 0; - batchElement.firstIndex = 0; - batchElement.indexBuffer = m->indexBuffer; - batchElement.indirectArgsBuffer = nullptr; - batchElement.isInstanced = false; - batchElement.numInstances = 1; - batchElement.sceneDataIndex = sceneDataIndex; - batch.elements.add(batchElement); - } - sceneDataIndex++; - } - if(sceneDataBuffer == nullptr || sceneDataBuffer->getNumElements() != sceneData.size()) - { - ShaderBufferCreateInfo createInfo = ShaderBufferCreateInfo { - .resourceData = { - .size = sceneData.size() * sizeof(PrimitiveSceneData), - .data = nullptr, - }, - .stride = (uint32)sceneData.size(), - }; - sceneDataBuffer = graphics->createShaderBuffer(createInfo); - } - sceneDataBuffer->updateContents(BulkResourceData { - .size = sceneData.size() * sizeof(PrimitiveSceneData), - .data = (uint8*)sceneData.data(), - }); - return result; -} - LightEnv Scene::getLightBuffer() { StaticArray dirLights; diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index 87cad2d..bc3534a 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -50,26 +50,16 @@ public: { return registry.get(entity); } - template - void view(Func func) requires std::is_invocable_v + template + void view(Func func) requires std::is_invocable_v || std::is_invocable_v { - registry.view().each(func); + registry.view().each(func); } - Array getStaticMeshes(); LightEnv getLightBuffer(); Component::Skybox getSkybox(); - Gfx::PShaderBuffer getSceneDataBuffer() const { return sceneDataBuffer; } Gfx::PGraphics getGraphics() const { return graphics; } entt::registry registry; private: - struct PrimitiveSceneData - { - Matrix4 localToWorld; - Matrix4 worldToLocal; - Vector4 actorLocation; - }; - Array sceneData; - Gfx::PShaderBuffer sceneDataBuffer; LightEnv lightEnv; PhysicsSystem physics; Gfx::PGraphics graphics; diff --git a/src/Engine/System/CMakeLists.txt b/src/Engine/System/CMakeLists.txt index f0880e5..caff95b 100644 --- a/src/Engine/System/CMakeLists.txt +++ b/src/Engine/System/CMakeLists.txt @@ -3,6 +3,8 @@ target_sources(Engine ComponentSystem.h Executor.h Executor.cpp + MeshUpdater.h + MeshUpdater.cpp SystemBase.h SystemGraph.h SystemGraph.cpp) @@ -11,6 +13,7 @@ target_sources(Engine PUBLIC FILE_SET HEADERS FILES ComponentSystem.h + MeshUpdater.h Executor.h SystemBase.h SystemGraph.h) \ No newline at end of file diff --git a/src/Engine/System/MeshUpdater.cpp b/src/Engine/System/MeshUpdater.cpp new file mode 100644 index 0000000..f619071 --- /dev/null +++ b/src/Engine/System/MeshUpdater.cpp @@ -0,0 +1,9 @@ +#include "MeshUpdater.h" + +using namespace Seele; +using namespace Seele::System; + +void MeshUpdater::update(Component::Transform& transform, Component::Mesh& mesh) +{ + mesh.vertexData->updateMesh(transform, mesh); +} diff --git a/src/Engine/System/MeshUpdater.h b/src/Engine/System/MeshUpdater.h new file mode 100644 index 0000000..82b21f3 --- /dev/null +++ b/src/Engine/System/MeshUpdater.h @@ -0,0 +1,17 @@ +#pragma once +#include "ComponentSystem.h" +#include "Component/Transform.h" +#include "Component/Mesh.h" + +namespace Seele +{ +namespace System +{ +class MeshUpdater : public ComponentSystem +{ +public: + virtual void update(Component::Transform& transform, Component::Mesh& mesh) override; +private: +}; +} // namespace System +} // namespace Seele \ No newline at end of file diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 90c5929..46eca36 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -11,9 +11,9 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate : View(graphics, window, createInfo, "Game") , gameInterface(dllPath) , renderGraph(RenderGraphBuilder::build( - DepthPrepass(graphics), + DepthPrepass(graphics, scene), LightCullingPass(graphics), - BasePass(graphics), + BasePass(graphics, scene), SkyboxRenderPass(graphics) )) { @@ -33,8 +33,16 @@ void GameView::beginUpdate() void GameView::update() { static auto startTime = std::chrono::high_resolution_clock::now(); + for (VertexData* vd : VertexData::getList()) + { + vd->resetMeshData(); + } systemGraph->run(threadPool, updateTime); scene->update(updateTime); + for (VertexData* vd : VertexData::getList()) + { + vd->createDescriptors(); + } auto endTime = std::chrono::high_resolution_clock::now(); std::chrono::duration duration = (endTime - startTime); updateTime = duration.count(); @@ -43,13 +51,7 @@ void GameView::update() void GameView::commitUpdate() { - depthPrepassData.staticDrawList = scene->getStaticMeshes(); - depthPrepassData.sceneDataBuffer = scene->getSceneDataBuffer(); - lightCullingData.lightEnv = scene->getLightBuffer(); - basePassData.staticDrawList = scene->getStaticMeshes(); - basePassData.sceneDataBuffer = scene->getSceneDataBuffer(); - basePassData.lightEnv = scene->getLightBuffer(); - skyboxData.skybox = scene->getSkybox(); + } void GameView::prepareRender() @@ -59,13 +61,7 @@ void GameView::prepareRender() void GameView::render() { - scene->view([&](Component::Camera& cam) - { - if(cam.mainCamera) - { - renderGraph.render(cam); - } - }); + renderGraph.render(camera->accessComponent()); } void GameView::reloadGame() diff --git a/src/Engine/Window/GameView.h b/src/Engine/Window/GameView.h index 2968817..82ccdf9 100644 --- a/src/Engine/Window/GameView.h +++ b/src/Engine/Window/GameView.h @@ -36,6 +36,7 @@ private: BasePassData basePassData; SkyboxPassData skyboxData; + PEntity camera; PScene scene; PSystemGraph systemGraph; dp::thread_pool<> threadPool; diff --git a/test.glsl b/test.glsl new file mode 100644 index 0000000..16c42c3 --- /dev/null +++ b/test.glsl @@ -0,0 +1,171 @@ +#version 450 +#extension GL_EXT_mesh_shader : require +layout(row_major) uniform; +layout(row_major) buffer; + +#line 3 0 +struct InstanceData_0 +{ + mat4x4 transformMatrix_0; +}; + + +#line 25 1 +layout(std430, binding = 0, set = 2) readonly buffer StructuredBuffer_InstanceData_t_0 { + InstanceData_0 _data[]; +} scene_instances_0; + +#line 20 2 +struct MeshData_0 +{ + uint numMeshlets_0; + uint meshletOffset_0; +}; + + +#line 8 0 +layout(std430, binding = 1, set = 2) readonly buffer StructuredBuffer_MeshData_t_0 { + MeshData_0 _data[]; +} scene_meshData_0; + +#line 5 3 +struct ViewParameter_0 +{ + mat4x4 viewMatrix_0; + mat4x4 projectionMatrix_0; + vec4 cameraPos_WS_0; + vec2 screenDimensions_0; +}; + +layout(binding = 0) +layout(std140) uniform _S1 +{ + mat4x4 viewMatrix_0; + mat4x4 projectionMatrix_0; + vec4 cameraPos_WS_0; + vec2 screenDimensions_0; +}viewParams_0; + +#line 14 1 +shared uint head_0; + + +#line 15 +shared mat4x4 localToClip_0; + + +#line 26 3 +struct Plane_0 +{ + vec3 n_0; + float d_0; +}; + +struct Frustum_0 +{ + Plane_0 sides_0[4]; + Plane_0 basePlane_0; +}; + + +#line 16 1 +shared Frustum_0 viewFrustum_0; + + +#line 7 +struct MeshPayload_0 +{ + uint instanceId_0[512]; + uint meshletId_0[512]; +}; + +taskPayloadSharedEXT MeshPayload_0 p_0; + + +#line 21 +layout(local_size_x = 128, local_size_y = 1, local_size_z = 1) in; +void main() +{ + +#line 21 + uint _S2 = gl_WorkGroupID.x; + + + + InstanceData_0 instance_0 = scene_instances_0._data[_S2]; + if(gl_LocalInvocationIndex == 0U) + { + head_0 = 0U; + localToClip_0 = ((((((instance_0.transformMatrix_0) * (viewParams_0.viewMatrix_0)))) * (viewParams_0.projectionMatrix_0))); + + viewFrustum_0.sides_0[0].n_0 = vec3(1.0, 0.0, 0.0); + viewFrustum_0.sides_0[0].d_0 = -1.0; + + viewFrustum_0.sides_0[1].n_0 = vec3(-1.0, 0.0, 0.0); + viewFrustum_0.sides_0[1].d_0 = 1.0; + + viewFrustum_0.sides_0[2].n_0 = vec3(0.0, -1.0, 0.0); + viewFrustum_0.sides_0[2].d_0 = 1.0; + + viewFrustum_0.sides_0[1].n_0 = vec3(0.0, 1.0, 0.0); + viewFrustum_0.sides_0[1].d_0 = -1.0; + + viewFrustum_0.basePlane_0.n_0 = vec3(0.0, 0.0, 1.0); + viewFrustum_0.basePlane_0.d_0 = 0.0; + +#line 26 + } + +#line 46 + barrier(); + MeshData_0 _S3 = scene_meshData_0._data[_S2]; + +#line 47 + if(gl_LocalInvocationIndex < 512U) + { + +#line 47 + uint i_0 = gl_LocalInvocationIndex; + +#line 47 + for(;;) + { + + uint m_0 = _S3.meshletOffset_0 + min(_S3.numMeshlets_0, i_0); + + + + uint index_0; + ((index_0) = atomicAdd((head_0), (1U))); + p_0.meshletId_0[index_0] = m_0; + p_0.instanceId_0[index_0] = _S2; + +#line 48 + uint i_1 = i_0 + 128U; + +#line 48 + if(i_1 < 512U) + { + } + else + { + +#line 48 + break; + } + +#line 48 + i_0 = i_1; + +#line 48 + } + +#line 48 + } + +#line 60 + barrier(); + EmitMeshTasksEXT((head_0), (1U), (1U)); + return; +} +