diff --git a/.gitmodules b/.gitmodules index 91ee4d1..b598ae1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,7 @@ url = https://github.com/d-bahr/CRCpp.git [submodule "external/vcpkg"] path = external/vcpkg - url = https://github.com/Microsoft/vcpkg.git \ No newline at end of file + url = https://github.com/Microsoft/vcpkg.git +[submodule "external/slang"] + path = external/slang + url = https://github.com/shader-slang/slang.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 01e8e39..435fc77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,7 @@ target_compile_definitions(Editor PRIVATE EDITOR=1) add_executable(AssetViewer "") target_link_libraries(AssetViewer PRIVATE Engine) target_include_directories(AssetViewer PRIVATE src/AssetViewer) - + if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) target_compile_options(Engine PUBLIC /std:c++20 /Zi /MP14 /W4 /wd4505) diff --git a/external/slang b/external/slang new file mode 160000 index 0000000..52b5bb4 --- /dev/null +++ b/external/slang @@ -0,0 +1 @@ +Subproject commit 52b5bb43fd2933a30b405e7938ff62b209eea026 diff --git a/res/shaders/LegacyPass.slang b/res/shaders/LegacyPass.slang index 2d7c1e2..21ab54e 100644 --- a/res/shaders/LegacyPass.slang +++ b/res/shaders/LegacyPass.slang @@ -7,7 +7,7 @@ import Scene; FragmentParameter vertexMain( VertexInput input ){ - InstanceData inst = pScene.instances[pOffsets.instanceOffset + input.instanceId]; + InstanceData inst = pScene.instances[input.instanceId]; VertexAttributes attr = pVertexData.getAttributes(input.vertexId); return attr.getParameter(inst.transformMatrix); } \ No newline at end of file diff --git a/res/shaders/MeshletPass.slang b/res/shaders/MeshletPass.slang index e0ca848..2185d8f 100644 --- a/res/shaders/MeshletPass.slang +++ b/res/shaders/MeshletPass.slang @@ -18,8 +18,8 @@ void meshMain( out vertices FragmentParameter vertices[MAX_VERTICES], out indices uint3 indices[MAX_PRIMITIVES] ){ - InstanceData inst = meshPayload.instanceData; - MeshData data = meshPayload.meshData; + InstanceData inst = pScene.instanceData[meshPayload.instanceId]; + MeshData data = pScene.meshData[meshPayload.instanceId]; MeshletDescription m = pScene.meshletInfos[data.meshletOffset + groupID]; SetMeshOutputCounts(m.vertexCount, m.primitiveCount); diff --git a/res/shaders/ViewCullingTask.slang b/res/shaders/ViewCullingTask.slang index d0b5029..88922c8 100644 --- a/res/shaders/ViewCullingTask.slang +++ b/res/shaders/ViewCullingTask.slang @@ -9,7 +9,7 @@ groupshared Frustum viewFrustum; [shader("amplification")] void taskMain( uint threadID: SV_GroupIndex, - uint groupID: SV_GroupThreadID + uint groupID: SV_GroupID ){ InstanceData instance = pScene.instances[pOffsets.instanceOffset + groupID]; MeshData mesh = pScene.meshData[pOffsets.instanceOffset + groupID]; diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index b7f9ad0..7f1f964 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -53,8 +53,7 @@ ParameterBlock pScene; struct MeshPayload { - InstanceData instanceData; - MeshData meshData; + uint instanceId; uint culledMeshlets[2048]; }; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 75adbb7..ada367f 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -124,28 +124,42 @@ void BasePass::render() assert(collection != nullptr); if (graphics->supportMeshShading()) { - Gfx::MeshPipelineCreateInfo pipelineInfo; - pipelineInfo.taskShader = collection->taskShader; - pipelineInfo.meshShader = collection->meshShader; - pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = collection->pipelineLayout; - pipelineInfo.renderPass = renderPass; - pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL; - pipelineInfo.multisampleState.samples = viewport->getSamples(); - pipelineInfo.colorBlend.attachmentCount = 2; + Gfx::MeshPipelineCreateInfo pipelineInfo = { + .taskShader = collection->taskShader, + .meshShader = collection->meshShader, + .fragmentShader = collection->fragmentShader, + .renderPass = renderPass, + .pipelineLayout = collection->pipelineLayout, + .multisampleState = { + .samples = viewport->getSamples(), + }, + .depthStencilState = { + .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, + }, + .colorBlend = { + .attachmentCount = 2, + }, + }; Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } else { - Gfx::LegacyPipelineCreateInfo pipelineInfo; - pipelineInfo.vertexShader = collection->vertexShader; - pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = collection->pipelineLayout; - pipelineInfo.renderPass = renderPass; - pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL; - pipelineInfo.multisampleState.samples = viewport->getSamples(); - pipelineInfo.colorBlend.attachmentCount = 2; + Gfx::LegacyPipelineCreateInfo pipelineInfo = { + .vertexShader = collection->vertexShader, + .fragmentShader = collection->fragmentShader, + .renderPass = renderPass, + .pipelineLayout = collection->pipelineLayout, + .multisampleState = { + .samples = viewport->getSamples(), + }, + .depthStencilState = { + .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, + }, + .colorBlend = { + .attachmentCount = 2, + }, + }; Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } @@ -154,9 +168,9 @@ void BasePass::render() command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet()); command->bindDescriptor(opaqueCulling); command->bindDescriptor(vertexData->getInstanceDataSet()); + command->bindDescriptor(vertexData->getInstanceDataSet()); for (const auto& drawCall : materialData.instances) { - command->bindDescriptor(vertexData->getInstanceDataSet()); command->bindDescriptor(drawCall.materialInstance->getDescriptorSet()); command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); if (graphics->supportMeshShading()) @@ -166,10 +180,11 @@ void BasePass::render() else { command->bindIndexBuffer(vertexData->getIndexBuffer()); + uint32 inst = drawCall.offsets.instanceOffset; for (const auto& meshData : drawCall.instanceMeshData) { // all meshlets of a mesh share the same indices offset - command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), 0); + command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++); } } } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 5effa60..48625fa 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -101,22 +101,29 @@ void DepthPrepass::render() } else { - Gfx::LegacyPipelineCreateInfo pipelineInfo; - pipelineInfo.vertexShader = collection->vertexShader; - pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = collection->pipelineLayout; - pipelineInfo.renderPass = renderPass; - pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER; - pipelineInfo.multisampleState.samples = viewport->getSamples(); - pipelineInfo.colorBlend.attachmentCount = 1; + Gfx::LegacyPipelineCreateInfo pipelineInfo = { + .vertexShader = collection->vertexShader, + .fragmentShader = collection->fragmentShader, + .renderPass = renderPass, + .pipelineLayout = collection->pipelineLayout, + .multisampleState = { + .samples = viewport->getSamples(), + }, + .depthStencilState = { + .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER, + }, + .colorBlend = { + .attachmentCount = 1, + }, + }; Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } command->bindDescriptor(vertexData->getVertexDataSet()); command->bindDescriptor(viewParamsSet); + command->bindDescriptor(vertexData->getInstanceDataSet()); for (const auto& drawCall : materialData.instances) { - command->bindDescriptor(vertexData->getInstanceDataSet()); command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); if (graphics->supportMeshShading()) { @@ -125,10 +132,11 @@ void DepthPrepass::render() else { command->bindIndexBuffer(vertexData->getIndexBuffer()); + uint32 inst = drawCall.offsets.instanceOffset; for (const auto& meshData : drawCall.instanceMeshData) { // all meshlets of a mesh share the same indices offset - command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), 0); + command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++); } } } diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index d303669..56026d2 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -60,6 +60,7 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform) }); const auto& data = meshData[mesh->id]; matInstanceData.instanceMeshData.add(data); + referencedInstance->updateDescriptor(); for (size_t i = 0; i < 0; ++i) { auto bounding = meshlets[data.meshletOffset + i].bounding; @@ -100,7 +101,6 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform) addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color }); } - referencedInstance->updateDescriptor(); } void VertexData::createDescriptors()