diff --git a/external/slang b/external/slang index 539b91c..febbeb1 160000 --- a/external/slang +++ b/external/slang @@ -1 +1 @@ -Subproject commit 539b91cb03952dec78b21ded7d150ce3598aa412 +Subproject commit febbeb140bea65180ff4be9b164207c582235d4d diff --git a/res/shaders/MeshletPass.slang b/res/shaders/MeshletPass.slang index ebd4f0c..f8d35eb 100644 --- a/res/shaders/MeshletPass.slang +++ b/res/shaders/MeshletPass.slang @@ -5,6 +5,9 @@ import MaterialParameter; struct PrimitiveAttributes { +#ifdef VISIBILITY + uint32_t prim : SV_PrimitiveID; +#endif bool cull: SV_CullPrimitive; }; @@ -19,9 +22,10 @@ void meshMain( out indices uint3 indices[MAX_PRIMITIVES], out primitives PrimitiveAttributes prim[MAX_PRIMITIVES] ) { + uint instanceId = meshPayload.instanceId; // meshlet number relative to start for this instance uint meshletNumber = meshPayload.culledMeshlets[groupID]; - InstanceData inst = pScene.instances[meshPayload.instanceId]; + InstanceData inst = pScene.instances[instanceId]; MeshletDescription m = pScene.meshletInfos[meshPayload.meshletOffset + meshletNumber]; MeshletCullingInfo cull = pScene.culledMeshlets[meshPayload.cullingOffset + meshletNumber]; SetMeshOutputCounts(m.vertexCount, m.primitiveCount); @@ -35,6 +39,9 @@ void meshMain( uint local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2]; indices[p] = uint3(local_idx0, local_idx1, local_idx2); prim[p].cull = cull.triangleCulled(p); +#ifdef VISIBILITY + prim[p].prim = encodePrimitive(p, meshletNumber, instanceId); +#endif } } for(uint i = threadID; i < MAX_VERTICES; i += MESH_GROUP_SIZE) diff --git a/res/shaders/VisibilityMeshletPass.slang b/res/shaders/VisibilityMeshletPass.slang deleted file mode 100644 index cf4930a..0000000 --- a/res/shaders/VisibilityMeshletPass.slang +++ /dev/null @@ -1,55 +0,0 @@ -import Common; -import Scene; -import VertexData; -import MaterialParameter; - -struct PrimitiveAttributes -{ - uint32_t prim : SV_PrimitiveID; - bool 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 FragmentParameter vertices[MAX_VERTICES], - out indices uint3 indices[MAX_PRIMITIVES], - out primitives PrimitiveAttributes prim[MAX_PRIMITIVES] -) { - // meshlet number relative to start for this instance - uint meshletNumber = meshPayload.culledMeshlets[groupID]; - InstanceData inst = pScene.instances[meshPayload.instanceId]; - MeshletDescription m = pScene.meshletInfos[meshPayload.meshletOffset + meshletNumber]; - MeshletCullingInfo cull = pScene.culledMeshlets[meshPayload.cullingOffset + meshletNumber]; - SetMeshOutputCounts(m.vertexCount, m.primitiveCount); - - for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE) - { - uint p = min(i, m.primitiveCount - 1); - { - uint local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0]; - uint local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1]; - uint local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2]; - indices[p] = uint3(local_idx0, local_idx1, local_idx2); - prim[p].cull = cull.triangleCulled(p); - //prim[p].prim = encodePrimitive(p, meshletNumber, meshPayload.instanceId); - } - } - for(uint i = threadID; i < MAX_VERTICES; i += MESH_GROUP_SIZE) - { - uint v = min(i, m.vertexCount - 1); - { - uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v]; -#ifdef POS_ONLY - VertexAttributes attr = pVertexData.getPosition(m.indicesOffset + vertexIndex); -#else - VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex); -#endif - vertices[v] = attr.getParameter(inst.transformMatrix); - } - } -} \ No newline at end of file diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index 2850832..24ac04d 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -74,12 +74,7 @@ ParameterBlock pScene; uint32_t encodePrimitive(uint32_t primitiveId, uint32_t meshletId, uint32_t instanceId) { - uint32_t encoded = instanceId; - encoded *= MAX_MESHLETS_PER_INSTANCE; - encoded += meshletId; - encoded *= MAX_PRIMITIVES; - encoded += primitiveId; - return encoded; + return primitiveId + (meshletId * uint(MAX_PRIMITIVES)) + (instanceId * uint(MAX_MESHLETS_PER_INSTANCE * MAX_PRIMITIVES)); } uint3 decodePrimitive(uint64_t encoded) @@ -94,9 +89,9 @@ uint3 decodePrimitive(uint64_t encoded) struct MeshPayload { + uint culledMeshlets[MAX_MESHLETS_PER_INSTANCE]; uint instanceId; uint meshletOffset; uint cullingOffset; - uint culledMeshlets[MAX_MESHLETS_PER_INSTANCE]; }; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 8edc78a..33b9e6e 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -42,11 +42,31 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) if (graphics->supportMeshShading()) { - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "DrawListTask"); + graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig { + .baseLayout = basePassLayout, + .taskFile = "DrawListTask", + .mainFile = "MeshletPass", + .fragmentFile = "BasePass", + .hasFragmentShader = true, + .useMeshShading = true, + .hasTaskShader = true, + .useMaterial = true, + .useVisibility = false, + }); } else { - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyPass", true, true, "BasePass"); + graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig { + .baseLayout = basePassLayout, + .taskFile = "", + .mainFile = "LegacyPass", + .fragmentFile = "BasePass", + .hasFragmentShader = true, + .useMeshShading = false, + .hasTaskShader = false, + .useMaterial = true, + .useVisibility = false, + }); } } @@ -88,17 +108,7 @@ void BasePass::render() graphics->beginRenderPass(renderPass); Array commands; - Gfx::ShaderPermutation permutation; - if (graphics->supportMeshShading()) - { - permutation.setTaskFile("DrawListTask"); - permutation.setMeshFile("MeshletPass"); - } - else - { - permutation.setVertexFile("LegacyPass"); - } - permutation.setFragmentFile("BasePass"); + Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("BasePass"); permutation.setViewCulling(useViewCulling); for (VertexData* vertexData : VertexData::getList()) { diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index 98c73e9..45a72b8 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -18,11 +18,31 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) }); if (graphics->supportMeshShading()) { - graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "VisibilityMeshletPass", false, true, "VisibilityPass", true, true, "DrawListTask"); + graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{ + .baseLayout = depthPrepassLayout, + .taskFile = "DrawListTask", + .mainFile = "MeshletPass", + .fragmentFile = "VisibilityPass", + .hasFragmentShader = true, + .useMeshShading = true, + .hasTaskShader = true, + .useMaterial = false, + .useVisibility = true, + }); } else { - graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "LegacyPass"); + graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{ + .baseLayout = depthPrepassLayout, + .taskFile = "", + .mainFile = "LegacyPass", + .fragmentFile = "VisibilityPass", + .hasFragmentShader = true, + .useMeshShading = false, + .hasTaskShader = false, + .useMaterial = false, + .useVisibility = true, + }); } } @@ -40,19 +60,9 @@ void CachedDepthPass::render() graphics->beginRenderPass(renderPass); Array commands; - Gfx::ShaderPermutation permutation; + Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("CachedDepthPass"); permutation.setPositionOnly(usePositionOnly); permutation.setViewCulling(useViewCulling); - if (graphics->supportMeshShading()) - { - permutation.setTaskFile("DrawListTask"); - permutation.setMeshFile("VisibilityMeshletPass"); - } - else - { - permutation.setVertexFile("LegacyPass"); - } - permutation.setFragmentFile("VisibilityPass"); for (VertexData *vertexData : VertexData::getList()) { permutation.setVertexData(vertexData->getTypeName()); diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 8fddea7..2ec112d 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -18,11 +18,31 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) }); if (graphics->supportMeshShading()) { - graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "VisibilityMeshletPass", false, true, "VisibilityPass", true, true, "DepthCullingTask"); + graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{ + .baseLayout = depthPrepassLayout, + .taskFile = "DepthCullingTask", + .mainFile = "MeshletPass", + .fragmentFile = "VisibilityPass", + .hasFragmentShader = true, + .useMeshShading = true, + .hasTaskShader = true, + .useMaterial = false, + .useVisibility = true, + }); } else { - graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass"); + graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{ + .baseLayout = depthPrepassLayout, + .taskFile = "", + .mainFile = "LegacyPass", + .fragmentFile = "VisibilityPass", + .hasFragmentShader = true, + .useMeshShading = false, + .hasTaskShader = false, + .useMaterial = false, + .useVisibility = true, + }); } } @@ -40,19 +60,9 @@ void DepthPrepass::render() graphics->beginRenderPass(renderPass); Array commands; - Gfx::ShaderPermutation permutation; + Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass"); permutation.setPositionOnly(usePositionOnly); permutation.setViewCulling(useViewCulling); - if (graphics->supportMeshShading()) - { - permutation.setTaskFile("DepthCullingTask"); - permutation.setMeshFile("VisibilityMeshletPass"); - } - else - { - permutation.setVertexFile("LegacyPass"); - } - permutation.setFragmentFile("VisibilityPass"); for (VertexData *vertexData : VertexData::getList()) { permutation.setVertexData(vertexData->getTypeName()); @@ -116,7 +126,7 @@ void DepthPrepass::render() command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset); if (graphics->supportMeshShading()) { - command->drawMesh(vertexData->getNumInstances(), 1, 1); + //command->drawMesh(vertexData->getNumInstances(), 1, 1); } else { diff --git a/src/Engine/Graphics/RenderPass/StaticBasePass.cpp b/src/Engine/Graphics/RenderPass/StaticBasePass.cpp deleted file mode 100644 index d916b7e..0000000 --- a/src/Engine/Graphics/RenderPass/StaticBasePass.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "StaticBasePass.h" -#include "Graphics/Shader.h" -#include "Graphics/StaticMeshVertexData.h" - -using namespace Seele; - -StaticBasePass::StaticBasePass(Gfx::PGraphics graphics, PScene scene) - : RenderPass(graphics, scene) -{ - basePassLayout = graphics->createPipelineLayout("BasePassLayout"); - - basePassLayout->addDescriptorLayout(viewParamsLayout); - basePassLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout()); - - lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData"); - // oLightIndexList - lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, }); - // oLightGrid - lightCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, }); - lightCullingLayout->create(); - - basePassLayout->addDescriptorLayout(lightCullingLayout); - if (graphics->supportMeshShading()) - { - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "StaticMeshletPass", false, true, "BasePass", true); - } - else - { - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticLegacyPass", false, true, "BasePass"); - } -} - -StaticBasePass::~StaticBasePass() -{ -} - -void StaticBasePass::beginFrame(const Component::Camera& cam) -{ - RenderPass::beginFrame(cam); - - lightCullingLayout->reset(); - opaqueCulling = lightCullingLayout->allocateDescriptorSet(); - transparentCulling = lightCullingLayout->allocateDescriptorSet(); -} - -void StaticBasePass::render() -{ - oLightIndexList->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - tLightIndexList->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - oLightGrid->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - tLightGrid->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); - - opaqueCulling->updateBuffer(0, oLightIndexList); - opaqueCulling->updateTexture(1, oLightGrid); - transparentCulling->updateBuffer(0, tLightIndexList); - transparentCulling->updateTexture(1, tLightGrid); - opaqueCulling->writeChanges(); - transparentCulling->writeChanges(); - - graphics->beginRenderPass(renderPass); - Array commands; - Gfx::ShaderPermutation permutation; - if (graphics->supportMeshShading()) - { - permutation.setTaskFile("StaticMeshletPass"); - permutation.setMeshFile("StaticMeshletPass"); - } - else - { - permutation.setVertexFile("StaticLegacyPass"); - } - permutation.setFragmentFile("BasePass"); - StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); - permutation.setVertexData(vd->getTypeName()); - - for (size_t i = 0; i < vd->getStaticMeshes().size(); ++i) - { - const auto& mesh = vd->getStaticMeshes()[i]; - permutation.setMaterial(mesh.material->getName()); - Gfx::PermutationId id(permutation); - - Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender"); - command->setViewport(viewport); - - const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); - 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 = 1; - 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 = 1; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); - } - command->bindDescriptor(vd->getVertexDataSet()); - command->bindDescriptor(viewParamsSet); - command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet()); - command->bindDescriptor(opaqueCulling); - command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 }); - for (const auto& instance : mesh.staticInstance) - { - command->bindDescriptor(instance.instance->getDescriptorSet()); - if (graphics->supportMeshShading()) - { - command->drawMesh(instance.meshletIds.size(), 1, 1); - } - else - { - //command->bindIndexBuffer(vd->getIndexBuffer()); - //uint32 instanceOffset = 0; - //for (const auto& meshData : vd->getMeshData(mapping.mapped)) - //{ - // if (meshData.numIndices > 0) - // { - // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); - // } - // instanceOffset++; - //} - } - } - commands.add(std::move(command)); - - } - graphics->executeCommands(std::move(commands)); - graphics->endRenderPass(); -} - -void StaticBasePass::endFrame() -{ -} - -void StaticBasePass::publishOutputs() -{ - colorAttachment = Gfx::RenderTargetAttachment(viewport, - Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); - resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); - -} - -void StaticBasePass::createRenderPass() -{ - depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); - depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL); - depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); - Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .colorAttachments = { colorAttachment, meshletIdAttachment }, - .depthAttachment = depthAttachment, - }; - Array dependency = { - { - .srcSubpass = ~0U, - .dstSubpass = 0, - .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - { - .srcSubpass = ~0U, - .dstSubpass = 0, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .srcAccess = Gfx::SE_ACCESS_NONE, - .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - }, - { - .srcSubpass = 0, - .dstSubpass = ~0U, - .srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - { - .srcSubpass = 0, - .dstSubpass = ~0U, - .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - }, - }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); - oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST"); - tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST"); - oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); - tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID"); -} diff --git a/src/Engine/Graphics/RenderPass/StaticBasePass.h b/src/Engine/Graphics/RenderPass/StaticBasePass.h deleted file mode 100644 index 299222f..0000000 --- a/src/Engine/Graphics/RenderPass/StaticBasePass.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "RenderPass.h" - -namespace Seele -{ -DECLARE_REF(CameraActor) -class StaticBasePass : public RenderPass -{ -public: - - StaticBasePass(Gfx::PGraphics graphics, PScene scene); - StaticBasePass(StaticBasePass&&) = default; - StaticBasePass& operator=(StaticBasePass&&) = default; - virtual ~StaticBasePass(); - virtual void beginFrame(const Component::Camera& cam) override; - virtual void render() override; - virtual void endFrame() override; - virtual void publishOutputs() override; - virtual void createRenderPass() override; -private: - Gfx::RenderTargetAttachment colorAttachment; - Gfx::RenderTargetAttachment depthAttachment; - Gfx::RenderTargetAttachment meshletIdAttachment; - Gfx::PShaderBuffer oLightIndexList; - Gfx::PShaderBuffer tLightIndexList; - Gfx::PTexture2D oLightGrid; - Gfx::PTexture2D tLightGrid; - Gfx::OTexture2D meshletIdTexture; - - Gfx::PDescriptorSet opaqueCulling; - Gfx::PDescriptorSet transparentCulling; - - PCameraActor source; - Gfx::OPipelineLayout basePassLayout; - Gfx::ODescriptorLayout lightCullingLayout; -}; -} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.cpp b/src/Engine/Graphics/RenderPass/StaticDepthPrepass.cpp deleted file mode 100644 index a875e6e..0000000 --- a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "StaticDepthPrepass.h" -#include "Graphics/StaticMeshVertexData.h" -#include "Graphics/Shader.h" - -using namespace Seele; - -StaticDepthPrepass::StaticDepthPrepass(Gfx::PGraphics graphics, PScene scene) - : RenderPass(graphics, scene) -{ - meshletCullingLayout = graphics->createDescriptorLayout("pCullingList"); - meshletCullingLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, }); - meshletCullingLayout->create(); - - depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout"); - depthPrepassLayout->addDescriptorLayout(viewParamsLayout); - depthPrepassLayout->addDescriptorLayout(meshletCullingLayout); - if (graphics->supportMeshShading()) - { - graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true); - } - else - { - graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass"); - } -} - -StaticDepthPrepass::~StaticDepthPrepass() -{ -} - -void StaticDepthPrepass::beginFrame(const Component::Camera& cam) -{ - RenderPass::beginFrame(cam); -} - -void StaticDepthPrepass::render() -{ - Array commands; - graphics->beginRenderPass(renderPass); - - Gfx::ShaderPermutation permutation; - if (graphics->supportMeshShading()) - { - permutation.setTaskFile("StaticMeshletPass"); - permutation.setMeshFile("StaticMeshletPass"); - } - else - { - permutation.setVertexFile("LegacyPass"); - } - StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); - permutation.setVertexData(vd->getTypeName()); - meshletCullingLayout->reset(); - for (size_t i = 0; i < vd->getStaticMeshes().size(); ++i) - { - const auto& mesh = vd->getStaticMeshes()[i]; - Gfx::PermutationId id(permutation); - - Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender"); - command->setViewport(viewport); - - const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); - assert(collection != nullptr); - if (graphics->supportMeshShading()) - { - 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, - }, - .colorBlend = { - .attachmentCount = 1, - }, - }; - 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; - pipelineInfo.multisampleState.samples = viewport->getSamples(); - pipelineInfo.colorBlend.attachmentCount = 1; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); - } - command->bindDescriptor(viewParamsSet); - command->bindDescriptor(vd->getVertexDataSet()); - command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 }); - for (const auto& instance : mesh.staticInstance) - { - Gfx::PDescriptorSet cullingSet = meshletCullingLayout->allocateDescriptorSet(); - cullingSet->updateBuffer(0, instance.culledMeshletBuffer); - cullingSet->writeChanges(); - command->bindDescriptor(cullingSet); - if (graphics->supportMeshShading()) - { - command->drawMesh(instance.meshletIds.size(), 1, 1); - } - else - { - //command->bindIndexBuffer(vd->getIndexBuffer()); - //uint32 instanceOffset = 0; - //for (const auto& meshData : vd->getMeshData(mapping.mapped)) - //{ - // if (meshData.numIndices > 0) - // { - // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); - // } - // instanceOffset++; - //} - } - } - commands.add(std::move(command)); - } - graphics->endRenderPass(); -} - -void StaticDepthPrepass::endFrame() -{ -} - -void StaticDepthPrepass::publishOutputs() -{ - -} - -void StaticDepthPrepass::createRenderPass() -{ - Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .depthAttachment = depthAttachment, - }; - Array dependency = { - { - .srcSubpass = ~0U, - .dstSubpass = 0, - .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - }, - { - .srcSubpass = 0, - .dstSubpass = ~0U, - .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - } - }; - renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport); -} diff --git a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h b/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h deleted file mode 100644 index b456a22..0000000 --- a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include "RenderPass.h" - -namespace Seele -{ -class StaticDepthPrepass : public RenderPass -{ -public: - StaticDepthPrepass(Gfx::PGraphics graphics, PScene scene); - StaticDepthPrepass(StaticDepthPrepass&&) = default; - StaticDepthPrepass& operator=(StaticDepthPrepass&&) = default; - virtual ~StaticDepthPrepass(); - virtual void beginFrame(const Component::Camera& cam) override; - virtual void render() override; - virtual void endFrame() override; - virtual void publishOutputs() override; - virtual void createRenderPass() override; -private: - Gfx::RenderTargetAttachment depthAttachment; - Gfx::OTexture2D depthBuffer; - Gfx::OPipelineLayout depthPrepassLayout; - Gfx::ODescriptorLayout meshletCullingLayout; -}; -} \ No newline at end of file diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp index f59ab75..fcf8ac0 100644 --- a/src/Engine/Graphics/Shader.cpp +++ b/src/Engine/Graphics/Shader.cpp @@ -9,7 +9,7 @@ using namespace Seele; using namespace Seele::Gfx; ShaderCompiler::ShaderCompiler(Gfx::PGraphics graphics) - : graphics(graphics) + : graphics(graphics) { } @@ -17,192 +17,170 @@ ShaderCompiler::~ShaderCompiler() { } -const ShaderCollection* ShaderCompiler::findShaders(PermutationId id) const +const ShaderCollection *ShaderCompiler::findShaders(PermutationId id) const { - return &shaders[id]; + return &shaders[id]; } void ShaderCompiler::registerMaterial(PMaterial material) { - materials[material->getName()] = material; - compile(); + materials[material->getName()] = material; + compile(); } -void ShaderCompiler::registerVertexData(VertexData* vd) +void ShaderCompiler::registerVertexData(VertexData *vd) { - vertexData[vd->getTypeName()] = vd; - compile(); + vertexData[vd->getTypeName()] = vd; + compile(); } -void ShaderCompiler::registerRenderPass(Gfx::PPipelineLayout layout, - std::string name, std::string mainFile, - bool useMaterials, - bool hasFragmentShader, - std::string fragmentFile, - bool useMeshShading, - bool hasTaskShader, - std::string taskFile) +void ShaderCompiler::registerRenderPass(std::string name, PassConfig config) { - passes[name] = PassConfig{ - .baseLayout = layout, - .taskFile = taskFile, - .mainFile = mainFile, - .fragmentFile = fragmentFile, - .hasFragmentShader = hasFragmentShader, - .useMeshShading = useMeshShading, - .hasTaskShader = hasTaskShader, - .useMaterial = useMaterials, - }; - compile(); + passes[name] = config; + compile(); } +ShaderPermutation ShaderCompiler::getTemplate(std::string name) +{ + ShaderPermutation permutation; + PassConfig &pass = passes[name]; + if (pass.useMeshShading) + { + permutation.setMeshFile(pass.mainFile); + } + else + { + permutation.setVertexFile(pass.mainFile); + } + if (pass.hasFragmentShader) + { + permutation.setFragmentFile(pass.fragmentFile); + } + if (pass.hasTaskShader) + { + permutation.setTaskFile(pass.taskFile); + } + permutation.setVisibilityPass(pass.useVisibility); + return permutation; +} void ShaderCompiler::compile() { - List> work; - for (const auto& [name, pass] : passes) - { - for (const auto& [vdName, vd] : vertexData) - { - if (pass.useMaterial) - { - for (const auto& [matName, mat] : materials) - { - for (int x = 0; x < 2; x++) - { - for (int y = 0; y < 2; y++) - { - work.add([=]() { - ShaderPermutation permutation; - permutation.setPositionOnly(x); + List> work; + for (const auto &[name, pass] : passes) + { + for (const auto &[vdName, vd] : vertexData) + { + if (pass.useMaterial) + { + for (const auto &[matName, mat] : materials) + { + for (int x = 0; x < 2; x++) + { + for (int y = 0; y < 2; y++) + { + work.add([=]() + { + ShaderPermutation permutation = getTemplate(name); + permutation.setPositionOnly(x); permutation.setViewCulling(y); - if (pass.useMeshShading) - { - permutation.setMeshFile(pass.mainFile); - } - else - { - permutation.setVertexFile(pass.mainFile); - } - if (pass.hasFragmentShader) - { - permutation.setFragmentFile(pass.fragmentFile); - } - if (pass.hasTaskShader) - { - permutation.setTaskFile(pass.taskFile); - } - permutation.setVertexData(vd->getTypeName()); - OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout); + permutation.setVertexData(vd->getTypeName()); + OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout); layout->addDescriptorLayout(vd->getVertexDataLayout()); layout->addDescriptorLayout(vd->getInstanceDataLayout()); layout->addDescriptorLayout(mat->getDescriptorLayout()); permutation.setMaterial(mat->getName()); - createShaders(permutation, std::move(layout)); - }); - } - } - - } - } - else - { - for (int x = 0; x < 2; x++) - { - for (int y = 0; y < 2; y++) - { - work.add([=]() { - ShaderPermutation permutation; + createShaders(permutation, std::move(layout)); }); + } + } + } + } + else + { + for (int x = 0; x < 2; x++) + { + for (int y = 0; y < 2; y++) + { + work.add([=]() + { + ShaderPermutation permutation = getTemplate(name); permutation.setPositionOnly(x); permutation.setViewCulling(y); - if (pass.useMeshShading) - { - permutation.setMeshFile(pass.mainFile); - } - else - { - permutation.setVertexFile(pass.mainFile); - } - if (pass.hasFragmentShader) - { - permutation.setFragmentFile(pass.fragmentFile); - } - if (pass.hasTaskShader) - { - permutation.setTaskFile(pass.taskFile); - } - permutation.setVertexData(vd->getTypeName()); - OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout); + permutation.setVertexData(vd->getTypeName()); + OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout->getName(), pass.baseLayout); layout->addDescriptorLayout(vd->getVertexDataLayout()); layout->addDescriptorLayout(vd->getInstanceDataLayout()); - createShaders(permutation, std::move(layout)); - }); - } - } - } - } - } - getThreadPool().runAndWait(std::move(work)); + createShaders(permutation, std::move(layout)); }); + } + } + } + } + } + getThreadPool().runAndWait(std::move(work)); } void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipelineLayout layout) { - PermutationId perm = PermutationId(permutation); - { - std::scoped_lock lock(shadersLock); - if (shaders.contains(perm)) - return; - } - ShaderCollection collection; + PermutationId perm = PermutationId(permutation); + { + std::scoped_lock lock(shadersLock); + if (shaders.contains(perm)) + return; + } + ShaderCollection collection; collection.pipelineLayout = std::move(layout); - ShaderCreateInfo createInfo; - createInfo.name = fmt::format("Material {0}", permutation.materialName); + ShaderCreateInfo createInfo; + createInfo.name = fmt::format("Material {0}", permutation.materialName); createInfo.rootSignature = collection.pipelineLayout; - if (std::strlen(permutation.materialName) > 0) + if (std::strlen(permutation.materialName) > 0) { createInfo.additionalModules.add(permutation.materialName); - createInfo.defines["MATERIAL_FILE_NAME"] = permutation.materialName; + createInfo.defines["MATERIAL_FILE_NAME"] = permutation.materialName; } - if (permutation.positionOnly) - { - createInfo.defines["POS_ONLY"] = "1"; - } - if (permutation.viewCulling) - { - createInfo.defines["VIEW_CULLING"] = "1"; - } - createInfo.typeParameter.add({ Pair("IVertexData", permutation.vertexDataName) }); - createInfo.additionalModules.add(permutation.vertexDataName); + if (permutation.positionOnly) + { + createInfo.defines["POS_ONLY"] = "1"; + } + if (permutation.viewCulling) + { + createInfo.defines["VIEW_CULLING"] = "1"; + } + if (permutation.visibilityPass) + { + createInfo.defines["VISIBILITY"] = "1"; + } + createInfo.typeParameter.add({Pair("IVertexData", permutation.vertexDataName)}); + createInfo.additionalModules.add(permutation.vertexDataName); - if (permutation.useMeshShading) - { - if (permutation.hasTaskShader) - { - createInfo.mainModule = permutation.taskFile; - createInfo.entryPoint = "taskMain"; - collection.taskShader = graphics->createTaskShader(createInfo); - } - createInfo.mainModule = permutation.vertexMeshFile; - createInfo.entryPoint = "meshMain"; - collection.meshShader = graphics->createMeshShader(createInfo); - } - else - { - createInfo.mainModule = permutation.vertexMeshFile; - createInfo.entryPoint = "vertexMain"; - collection.vertexShader = graphics->createVertexShader(createInfo); - } + if (permutation.useMeshShading) + { + if (permutation.hasTaskShader) + { + createInfo.mainModule = permutation.taskFile; + createInfo.entryPoint = "taskMain"; + collection.taskShader = graphics->createTaskShader(createInfo); + } + createInfo.mainModule = permutation.vertexMeshFile; + createInfo.entryPoint = "meshMain"; + collection.meshShader = graphics->createMeshShader(createInfo); + } + else + { + createInfo.mainModule = permutation.vertexMeshFile; + createInfo.entryPoint = "vertexMain"; + collection.vertexShader = graphics->createVertexShader(createInfo); + } - if (permutation.hasFragment) - { - createInfo.mainModule = permutation.fragmentFile; - createInfo.entryPoint = "fragmentMain"; - collection.fragmentShader = graphics->createFragmentShader(createInfo); - } - collection.pipelineLayout->create(); - { - std::scoped_lock lock(shadersLock); - shaders[perm] = std::move(collection); - } + if (permutation.hasFragment) + { + createInfo.mainModule = permutation.fragmentFile; + createInfo.entryPoint = "fragmentMain"; + collection.fragmentShader = graphics->createFragmentShader(createInfo); + } + collection.pipelineLayout->create(); + { + std::scoped_lock lock(shadersLock); + shaders[perm] = std::move(collection); + } } diff --git a/src/Engine/Graphics/Shader.h b/src/Engine/Graphics/Shader.h index 275d026..a6b341f 100644 --- a/src/Engine/Graphics/Shader.h +++ b/src/Engine/Graphics/Shader.h @@ -64,6 +64,7 @@ struct ShaderPermutation uint8 useMaterial; uint8 positionOnly; uint8 viewCulling; + uint8 visibilityPass; //TODO: lightmapping etc ShaderPermutation() { @@ -112,6 +113,10 @@ struct ShaderPermutation { viewCulling = enable; } + void setVisibilityPass(bool enable) + { + visibilityPass = enable; + } }; //Hashed ShaderPermutation for fast lookup struct PermutationId @@ -140,6 +145,19 @@ struct ShaderCollection OMeshShader meshShader; OFragmentShader fragmentShader; }; + +struct PassConfig +{ + Gfx::PPipelineLayout baseLayout; + std::string taskFile = ""; + std::string mainFile = ""; + std::string fragmentFile = ""; + bool hasFragmentShader = false; + bool useMeshShading = false; + bool hasTaskShader = false; + bool useMaterial = false; + bool useVisibility = false; +}; class ShaderCompiler { public: @@ -148,15 +166,8 @@ public: const ShaderCollection* findShaders(PermutationId id) const; void registerMaterial(PMaterial material); void registerVertexData(VertexData* vertexData); - void registerRenderPass(Gfx::PPipelineLayout baseLayout, - std::string name, - std::string mainFile, - bool useMaterials = false, - bool hasFragmentShader = false, - std::string fragmentFile = "", - bool useMeshShading = false, - bool hasTaskShader = false, - std::string taskFile = ""); + void registerRenderPass(std::string name, PassConfig config); + ShaderPermutation getTemplate(std::string name); private: void compile(); void createShaders(ShaderPermutation permutation, OPipelineLayout layout); @@ -164,17 +175,6 @@ private: Map shaders; Map materials; Map vertexData; - struct PassConfig - { - Gfx::PPipelineLayout baseLayout; - std::string taskFile; - std::string mainFile; - std::string fragmentFile; - bool hasFragmentShader; - bool useMeshShading; - bool hasTaskShader; - bool useMaterial; - }; Map passes; Gfx::PGraphics graphics; }; diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index fe1e386..0501fbd 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -28,7 +28,7 @@ Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& create option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE; option[3].name = slang::CompilerOptionName::DebugInformationFormat; option[3].value.kind = slang::CompilerOptionValueKind::Int; - option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_DEFAULT; + option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_PDB; sessionDesc.compilerOptionEntries = option.data(); sessionDesc.compilerOptionEntryCount = option.size();