From effb0c621449f1413b766e9aef066f9590debcb4 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Thu, 9 Nov 2023 22:15:51 +0100 Subject: [PATCH] its running i think --- CMakeSettings.json | 1 - res/shaders/BasePass.slang | 3 +- res/shaders/LegacyBasePass.slang | 5 +- res/shaders/MeshletBasePass.slang | 4 +- res/shaders/lib/MaterialParameter.slang | 5 + res/shaders/lib/SkinnedMeshVertexData.slang | 30 ----- res/shaders/lib/StaticMeshVertexData.slang | 43 ++----- res/shaders/lib/VertexData.slang | 6 - src/Engine/Graphics/Graphics.h | 6 +- src/Engine/Graphics/Initializer.cpp | 10 ++ src/Engine/Graphics/Initializer.h | 18 +-- src/Engine/Graphics/RenderPass/BasePass.cpp | 19 ++- .../Graphics/RenderPass/DepthPrepass.cpp | 36 +++--- src/Engine/Graphics/RenderPass/DepthPrepass.h | 10 +- .../Graphics/RenderPass/LightCullingPass.cpp | 12 +- .../Graphics/RenderPass/LightCullingPass.h | 6 +- .../Graphics/RenderPass/SkyboxRenderPass.cpp | 54 +++++---- .../Graphics/RenderPass/SkyboxRenderPass.h | 9 +- src/Engine/Graphics/RenderPass/TextPass.cpp | 9 +- src/Engine/Graphics/RenderPass/TextPass.h | 4 +- src/Engine/Graphics/RenderPass/UIPass.cpp | 6 +- src/Engine/Graphics/RenderPass/UIPass.h | 3 +- src/Engine/Graphics/Resources.h | 9 +- src/Engine/Graphics/Shader.cpp | 12 +- src/Engine/Graphics/Shader.h | 40 ++++++- src/Engine/Graphics/VertexData.cpp | 9 +- src/Engine/Graphics/VertexData.h | 4 +- src/Engine/Graphics/Vulkan/Graphics.cpp | 12 +- src/Engine/Graphics/Vulkan/Graphics.h | 6 +- src/Engine/Graphics/Vulkan/Pipeline.cpp | 12 +- src/Engine/Graphics/Vulkan/Pipeline.h | 4 +- src/Engine/Graphics/Vulkan/PipelineCache.cpp | 110 ++++++++++++------ src/Engine/Graphics/Vulkan/PipelineCache.h | 8 +- src/Engine/Graphics/Vulkan/Shader.cpp | 23 ++-- 34 files changed, 299 insertions(+), 249 deletions(-) diff --git a/CMakeSettings.json b/CMakeSettings.json index 8d62c21..7a80985 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -6,7 +6,6 @@ "ctestCommandArgs": "", "configurationType": "Debug", "generator": "Visual Studio 17 2022 Win64", - "addressSanitizerEnabled": true, "intelliSenseMode": "windows-msvc-x64", "inheritEnvironments": [ "msvc_x64" ], "cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=\"\" -DCMAKE_PLATFORM=x64", diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index edc87c4..042d149 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -14,9 +14,8 @@ struct LightCullingData ParameterBlock pLightCullingData; [shader("pixel")] -void pixelMain(in VertexAttributes attribs, out float4 baseColor) +void pixelMain(in MaterialParameter params : PARAMETER, out float4 baseColor) { - MaterialParameter params = attribs.create(); BRDF brdf = pMaterial.prepare(params); float3 result = float3(0, 0, 0); for(int i = 0; i < pLightEnv.numDirectionalLights; ++i) diff --git a/res/shaders/LegacyBasePass.slang b/res/shaders/LegacyBasePass.slang index e2a562e..77820df 100644 --- a/res/shaders/LegacyBasePass.slang +++ b/res/shaders/LegacyBasePass.slang @@ -1,4 +1,5 @@ import VertexData; +import MaterialParameter; struct InstanceData { @@ -13,11 +14,11 @@ struct Scene ParameterBlock pScene; [shader("vertex")] -IVertexAttributes vertexMain( +VertexAttributes vertexMain( uint vertexId: SV_VertexID, uint instanceId: SV_InstanceID, ){ InstanceData inst = pScene.instances[instanceId]; - IVertexAttributes attr = pVertexData.getAttributes(vertexId, inst.transformMatrix); + VertexAttributes attr = pVertexData.getAttributes(vertexId, inst.transformMatrix); return attr; } \ No newline at end of file diff --git a/res/shaders/MeshletBasePass.slang b/res/shaders/MeshletBasePass.slang index 6a1bd88..3d091f1 100644 --- a/res/shaders/MeshletBasePass.slang +++ b/res/shaders/MeshletBasePass.slang @@ -61,7 +61,7 @@ void taskMain( DispatchMesh(head, 1, 1, p); } -groupshared IVertexAttributes gs_vertices[MAX_VERTICES]; +groupshared VertexAttributes gs_vertices[MAX_VERTICES]; groupshared uint3 gs_indices[MAX_PRIMITIVES]; groupshared uint gs_numVertices; groupshared uint gs_numPrimitives; @@ -78,7 +78,7 @@ void meshMain( in uint threadID: SV_GroupIndex, in uint groupID: SV_GroupID, in payload MeshPayload meshPayload, - out Vertices vertices, + out Vertices vertices, out Indices indices ){ InstanceData inst = pScene.instances[meshPayload.instanceId[groupID]]; diff --git a/res/shaders/lib/MaterialParameter.slang b/res/shaders/lib/MaterialParameter.slang index 88b2bdd..77ae5a6 100644 --- a/res/shaders/lib/MaterialParameter.slang +++ b/res/shaders/lib/MaterialParameter.slang @@ -9,3 +9,8 @@ struct MaterialParameter float3 viewDir_TS; } +struct VertexAttributes +{ + MaterialParameter parameter : PARAMETER; + float4 clipPosition: SV_POSITION; +}; diff --git a/res/shaders/lib/SkinnedMeshVertexData.slang b/res/shaders/lib/SkinnedMeshVertexData.slang index fd2ac96..7ad4c59 100644 --- a/res/shaders/lib/SkinnedMeshVertexData.slang +++ b/res/shaders/lib/SkinnedMeshVertexData.slang @@ -2,36 +2,6 @@ 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) diff --git a/res/shaders/lib/StaticMeshVertexData.slang b/res/shaders/lib/StaticMeshVertexData.slang index fa32105..73142cf 100644 --- a/res/shaders/lib/StaticMeshVertexData.slang +++ b/res/shaders/lib/StaticMeshVertexData.slang @@ -2,45 +2,24 @@ import Common; import VertexData; import MaterialParameter; -struct StaticMeshVertexAttributes : IVertexAttributes -{ - float4 clipPosition: SV_Position; - float3 worldPosition: POSITION0; - float2 texCoords: TEXCOORD0; - float3 normal: NORMAL0; - float3 tangent: TANGENT0; - float3 biTangent: BITANGENT0; - - MaterialParameter create() - { - MaterialParameter result; - result.worldPosition = worldPosition; - result.texCoords = texCoords; - result.normal = normal; - result.tangent = tangent; - result.biTangent = biTangent; - return result; - } - -}; - struct StaticMeshVertexData : IVertexData { - typedef StaticMeshVertexAttributes VertexAttributes; - StaticMeshVertexAttributes getAttributes(uint index, float4x4 transform) + VertexAttributes getAttributes(uint index, float4x4 transform) { - StaticMeshVertexAttributes attr; + VertexAttributes attributes; + MaterialParameter params; float4 localPos = float4(positions[index], 1); float4 worldPos = mul(transform, localPos); float4 viewPos = mul(pViewParams.viewMatrix, worldPos); float4 clipPos = mul(pViewParams.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; + params.worldPosition = worldPos.xyz; + params.texCoords = texCoords[index]; + params.normal = normals[index]; + params.tangent = tangents[index]; + params.biTangent = biTangents[index]; + attributes.parameter = params; + attributes.clipPosition = clipPos; + return attributes; } StructuredBuffer positions; StructuredBuffer texCoords; diff --git a/res/shaders/lib/VertexData.slang b/res/shaders/lib/VertexData.slang index 06fdacc..25338f4 100644 --- a/res/shaders/lib/VertexData.slang +++ b/res/shaders/lib/VertexData.slang @@ -1,13 +1,7 @@ import MaterialParameter; -interface IVertexAttributes -{ - MaterialParameter create(); -}; - interface IVertexData { - associatedtype VertexAttributes : IVertexAttributes; VertexAttributes getAttributes(uint index, float4x4 transform); }; ParameterBlock pVertexData; \ No newline at end of file diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 729851c..9037f3d 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -71,9 +71,9 @@ public: virtual OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0; virtual OMeshShader createMeshShader(const ShaderCreateInfo& createInfo) = 0; virtual OTaskShader createTaskShader(const ShaderCreateInfo& createInfo) = 0; - virtual OGraphicsPipeline createGraphicsPipeline(const LegacyPipelineCreateInfo& createInfo) = 0; - virtual OGraphicsPipeline createGraphicsPipeline(const MeshPipelineCreateInfo& createInfo) = 0; - virtual OComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0; + virtual PGraphicsPipeline createGraphicsPipeline(LegacyPipelineCreateInfo createInfo) = 0; + virtual PGraphicsPipeline createGraphicsPipeline(MeshPipelineCreateInfo createInfo) = 0; + virtual PComputePipeline createComputePipeline(ComputePipelineCreateInfo createInfo) = 0; virtual OSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0; virtual ODescriptorLayout createDescriptorLayout(const std::string& name = "") = 0; diff --git a/src/Engine/Graphics/Initializer.cpp b/src/Engine/Graphics/Initializer.cpp index a9e3c1b..f897854 100644 --- a/src/Engine/Graphics/Initializer.cpp +++ b/src/Engine/Graphics/Initializer.cpp @@ -1,4 +1,5 @@ #include "Initializer.h" +#include "Descriptor.h" using namespace Seele; using namespace Seele::Gfx; @@ -90,3 +91,12 @@ MeshPipelineCreateInfo::MeshPipelineCreateInfo() MeshPipelineCreateInfo::~MeshPipelineCreateInfo() { } + +ComputePipelineCreateInfo::ComputePipelineCreateInfo() +{ + std::memset((void*)this, 0, sizeof(*this)); +} + +ComputePipelineCreateInfo::~ComputePipelineCreateInfo() +{ +} diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index 4070c90..6061895 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -203,12 +203,14 @@ struct LegacyPipelineCreateInfo PVertexShader vertexShader; PFragmentShader fragmentShader; PRenderPass renderPass; - PPipelineLayout pipelineLayout; + OPipelineLayout pipelineLayout; MultisampleState multisampleState; RasterizationState rasterizationState; DepthStencilState depthStencilState; ColorBlendState colorBlend; LegacyPipelineCreateInfo(); + LegacyPipelineCreateInfo(LegacyPipelineCreateInfo&& rhs) = default; + LegacyPipelineCreateInfo& operator=(LegacyPipelineCreateInfo&& rhs) = default; ~LegacyPipelineCreateInfo(); }; @@ -218,22 +220,24 @@ struct MeshPipelineCreateInfo PMeshShader meshShader; PFragmentShader fragmentShader; PRenderPass renderPass; - PPipelineLayout pipelineLayout; + OPipelineLayout pipelineLayout; MultisampleState multisampleState; RasterizationState rasterizationState; DepthStencilState depthStencilState; ColorBlendState colorBlend; MeshPipelineCreateInfo(); + MeshPipelineCreateInfo(MeshPipelineCreateInfo&& rhs) = default; + MeshPipelineCreateInfo& operator=(MeshPipelineCreateInfo&& rhs) = default; ~MeshPipelineCreateInfo(); }; struct ComputePipelineCreateInfo { Gfx::PComputeShader computeShader; - Gfx::PPipelineLayout pipelineLayout; - ComputePipelineCreateInfo() - { - std::memset((void*)this, 0, sizeof(*this)); - } + Gfx::OPipelineLayout pipelineLayout; + ComputePipelineCreateInfo(); + ComputePipelineCreateInfo(ComputePipelineCreateInfo&& rhs) = default; + ComputePipelineCreateInfo& operator=(ComputePipelineCreateInfo&& rhs) = default; + ~ComputePipelineCreateInfo(); }; } // namespace Gfx } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 2fa05c9..ed34862 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -121,10 +121,10 @@ void BasePass::render() pipelineInfo.taskShader = collection->taskShader; pipelineInfo.meshShader = collection->meshShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = layout; + pipelineInfo.pipelineLayout = std::move(layout); pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } else @@ -133,10 +133,10 @@ void BasePass::render() pipelineInfo.vertexDeclaration = collection->vertexDeclaration; pipelineInfo.vertexShader = collection->vertexShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = layout; + pipelineInfo.pipelineLayout = std::move(layout); pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } @@ -156,8 +156,15 @@ void BasePass::render() for(const auto& mesh : instance.meshes) { uint32 vertexOffset = vertexData->getMeshOffset(mesh.id); - command->bindIndexBuffer(mesh.indexBuffer); - command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset); + if (mesh.indexBuffer != nullptr) + { + command->bindIndexBuffer(mesh.indexBuffer); + command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset); + } + else + { + command->draw(vertexData->getMeshVertexCount(mesh.id), 1, vertexOffset, instanceOffset); + } } } } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 936a45f..376fcd1 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -13,7 +13,7 @@ using namespace Seele; DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) - , descriptorSets(4) + , descriptorSets(3) { UniformBufferCreateInfo uniformInitializer; @@ -39,18 +39,14 @@ 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); Gfx::ShaderPermutation permutation; - permutation.hasFragment = false; if(graphics->supportMeshShading()) { - permutation.useMeshShading = true; - permutation.hasTaskShader = true; - std::strncpy(permutation.taskFile, "MeshletBasePass", sizeof("MeshletBasePass")); - std::strncpy(permutation.vertexMeshFile, "MeshletBasePass", sizeof("MeshletBasePass")); + permutation.setTaskFile("MeshletBasePass"); + permutation.setMeshFile("MeshletBasePass"); } else { - permutation.useMeshShading = false; - std::strncpy(permutation.vertexMeshFile, "LegacyBasePass", sizeof("LegacyBasePass")); + permutation.setVertexFile("LegacyBasePass"); } graphics->beginRenderPass(renderPass); for (VertexData* vertexData : VertexData::getList()) @@ -65,12 +61,11 @@ void DepthPrepass::render() // Material => per material // VertexData => per meshtype // SceneData => per material instance - std::strncpy(permutation.materialName, materialData.material->getName().c_str(), sizeof(permutation.materialName)); Gfx::PermutationId id(permutation); Gfx::PRenderCommand command = graphics->createRenderCommand("DepthRender"); Gfx::OPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout); - layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); + //layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); layout->addDescriptorLayout(INDEX_VERTEX_DATA, vertexData->getVertexDataLayout()); layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout()); layout->create(); @@ -83,10 +78,10 @@ void DepthPrepass::render() pipelineInfo.taskShader = collection->taskShader; pipelineInfo.meshShader = collection->meshShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = layout; + pipelineInfo.pipelineLayout = std::move(layout); pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } else @@ -95,17 +90,17 @@ void DepthPrepass::render() pipelineInfo.vertexDeclaration = collection->vertexDeclaration; pipelineInfo.vertexShader = collection->vertexShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = layout; + pipelineInfo.pipelineLayout = std::move(layout); pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(pipelineInfo); + Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } descriptorSets[INDEX_VERTEX_DATA] = vertexData->getVertexDataSet(); for (const auto& [_, instance] : materialData.instances) { - descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); + //descriptorSets[INDEX_MATERIAL] = instance.materialInstance->getDescriptorSet(); descriptorSets[INDEX_SCENE_DATA] = instance.descriptorSet; command->bindDescriptor(descriptorSets); if(graphics->supportMeshShading()) @@ -118,8 +113,15 @@ void DepthPrepass::render() for(const auto& mesh : instance.meshes) { uint32 vertexOffset = vertexData->getMeshOffset(mesh.id); - command->bindIndexBuffer(mesh.indexBuffer); - command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset); + if (mesh.indexBuffer != nullptr) + { + command->bindIndexBuffer(mesh.indexBuffer); + command->drawIndexed(mesh.indexBuffer->getNumIndices(), 1, 0, vertexOffset, instanceOffset); + } + else + { + command->draw(vertexData->getMeshVertexCount(mesh.id), 1, vertexOffset, instanceOffset); + } } } } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index 033e628..54c0f52 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -25,12 +25,10 @@ private: Gfx::OPipelineLayout depthPrepassLayout; // Set 0: viewParameter - // Set 1: materials, generated - constexpr static uint32 INDEX_MATERIAL = 1; - // Set 2: vertices, from VertexData - constexpr static uint32 INDEX_VERTEX_DATA = 2; - // Set 3: mesh data, either index buffer or meshlet data - constexpr static uint32 INDEX_SCENE_DATA = 3; + // Set 1: vertices, from VertexData + constexpr static uint32 INDEX_VERTEX_DATA = 1; + // Set 2: mesh data, either index buffer or meshlet data + constexpr static uint32 INDEX_SCENE_DATA = 2; Gfx::ODescriptorLayout sceneDataLayout; }; DEFINE_REF(DepthPrepass) diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 277fd11..95750c0 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -117,7 +117,7 @@ void LightCullingPass::publishOutputs() lightEnv = scene->getLightEnvironment(); - cullingLayout = graphics->createPipelineLayout(); + Gfx::OPipelineLayout cullingLayout = graphics->createPipelineLayout(); cullingLayout->addDescriptorLayout(0, viewParamsLayout); cullingLayout->addDescriptorLayout(1, lightEnv->getDescriptorLayout()); cullingLayout->addDescriptorLayout(2, cullingDescriptorLayout); @@ -132,8 +132,8 @@ void LightCullingPass::publishOutputs() Gfx::ComputePipelineCreateInfo pipelineInfo; pipelineInfo.computeShader = cullingShader; - pipelineInfo.pipelineLayout = cullingLayout; - cullingPipeline = graphics->createComputePipeline(pipelineInfo); + pipelineInfo.pipelineLayout = std::move(cullingLayout); + cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo)); uint32 counterReset = 0; ShaderBufferCreateInfo structInfo = @@ -203,7 +203,7 @@ void LightCullingPass::setupFrustums() frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout"); frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - frustumLayout = graphics->createPipelineLayout(); + Gfx::OPipelineLayout frustumLayout = graphics->createPipelineLayout(); frustumLayout->addDescriptorLayout(0, viewParamsLayout); frustumLayout->addDescriptorLayout(1, frustumDescriptorLayout); frustumLayout->create(); @@ -216,8 +216,8 @@ void LightCullingPass::setupFrustums() Gfx::ComputePipelineCreateInfo pipelineInfo; pipelineInfo.computeShader = frustumShader; - pipelineInfo.pipelineLayout = frustumLayout; - frustumPipeline = graphics->createComputePipeline(pipelineInfo); + pipelineInfo.pipelineLayout = std::move(frustumLayout); + frustumPipeline = graphics->createComputePipeline(std::move(pipelineInfo)); Gfx::OUniformBuffer frustumDispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ .sourceData = { diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index 34cedc2..3ed3602 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -48,8 +48,7 @@ private: Gfx::ODescriptorLayout frustumDescriptorLayout; Gfx::PDescriptorSet frustumDescriptorSet; Gfx::OComputeShader frustumShader; - Gfx::OPipelineLayout frustumLayout; - Gfx::OComputePipeline frustumPipeline; + Gfx::PComputePipeline frustumPipeline; PLightEnvironment lightEnv; Gfx::PTexture2D depthAttachment; @@ -63,8 +62,7 @@ private: Gfx::PDescriptorSet cullingDescriptorSet; Gfx::ODescriptorLayout cullingDescriptorLayout; Gfx::OComputeShader cullingShader; - Gfx::OPipelineLayout cullingLayout; - Gfx::OComputePipeline cullingPipeline; + Gfx::PComputePipeline cullingPipeline; }; DEFINE_REF(LightCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp index 022a5a2..720e658 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp @@ -96,13 +96,16 @@ void SkyboxRenderPass::beginFrame(const Component::Camera& cam) uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.data = (uint8*)&viewParams; viewParamsBuffer->updateContents(uniformUpdate); - descriptorLayout->reset(); - descriptorSet = descriptorLayout->allocateDescriptorSet(); - descriptorSet->updateBuffer(0, viewParamsBuffer); - descriptorSet->updateTexture(1, skybox.day); - descriptorSet->updateTexture(2, skybox.night); - descriptorSet->updateSampler(3, skyboxSampler); - descriptorSet->writeChanges(); + skyboxDataLayout->reset(); + textureLayout->reset(); + skyboxDataSet = skyboxDataLayout->allocateDescriptorSet(); + skyboxDataSet->updateBuffer(0, viewParamsBuffer); + skyboxDataSet->writeChanges(); + textureSet = textureLayout->allocateDescriptorSet(); + textureSet->updateTexture(0, skybox.day); + textureSet->updateTexture(1, skybox.night); + textureSet->updateSampler(2, skyboxSampler); + textureSet->writeChanges(); } void SkyboxRenderPass::render() @@ -111,10 +114,8 @@ void SkyboxRenderPass::render() Gfx::PRenderCommand renderCommand = graphics->createRenderCommand("SkyboxRender"); renderCommand->setViewport(viewport); renderCommand->bindPipeline(pipeline); - renderCommand->bindDescriptor(descriptorSet); + renderCommand->bindDescriptor({skyboxDataSet, textureSet}); renderCommand->bindVertexBuffer({ cubeBuffer }); - renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vector), &skybox.fogColor); - renderCommand->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, sizeof(Vector), sizeof(float), &skybox.blendFactor); renderCommand->draw(36, 1, 0, 0); graphics->executeCommands(Array{ renderCommand }); graphics->endRenderPass(); @@ -136,22 +137,14 @@ void SkyboxRenderPass::publishOutputs() }; viewParamsBuffer = graphics->createUniformBuffer(viewCreateInfo); - descriptorLayout = graphics->createDescriptorLayout("SkyboxDescLayout"); - descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); - descriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); - descriptorLayout->create(); - - pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(0, descriptorLayout); - pipelineLayout->addPushConstants(Gfx::SePushConstantRange{ - .stageFlags = Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, - .offset = 0, - .size = sizeof(Vector4), - }); - - pipelineLayout->create(); + skyboxDataLayout = graphics->createDescriptorLayout("SkyboxDescLayout"); + skyboxDataLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + skyboxDataLayout->create(); + textureLayout = graphics->createDescriptorLayout(); + textureLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + textureLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); + textureLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); + textureLayout->create(); skyboxSampler = graphics->createSamplerState({}); } @@ -185,6 +178,11 @@ void SkyboxRenderPass::createRenderPass() } }); + Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); + pipelineLayout->addDescriptorLayout(0, skyboxDataLayout); + pipelineLayout->addDescriptorLayout(0, textureLayout); + pipelineLayout->create(); + Gfx::LegacyPipelineCreateInfo gfxInfo; gfxInfo.vertexDeclaration = declaration; gfxInfo.vertexShader = vertexShader; @@ -192,7 +190,7 @@ void SkyboxRenderPass::createRenderPass() gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL; gfxInfo.rasterizationState.lineWidth = 5.f; gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - gfxInfo.pipelineLayout = pipelineLayout; + gfxInfo.pipelineLayout = std::move(pipelineLayout); gfxInfo.renderPass = renderPass; - pipeline = graphics->createGraphicsPipeline(gfxInfo); + pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); } diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h index 5252d4c..46f433e 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h @@ -23,13 +23,14 @@ public: private: Gfx::OVertexBuffer cubeBuffer; Gfx::OUniformBuffer viewParamsBuffer; - Gfx::ODescriptorLayout descriptorLayout; - Gfx::PDescriptorSet descriptorSet; - Gfx::OPipelineLayout pipelineLayout; + Gfx::ODescriptorLayout skyboxDataLayout; + Gfx::PDescriptorSet skyboxDataSet; + Gfx::ODescriptorLayout textureLayout; + Gfx::PDescriptorSet textureSet; Gfx::OVertexDeclaration declaration; Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; - Gfx::OGraphicsPipeline pipeline; + Gfx::PGraphicsPipeline pipeline; Gfx::OSamplerState skyboxSampler; Component::Skybox skybox; }; diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index 01a8e73..c569507 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -85,7 +85,7 @@ void TextPass::render() command->bindDescriptor({generalSet, resource.textureArraySet}); command->bindVertexBuffer({resource.vertexBuffer}); - command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData); + command->pushConstants(layoutRef, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData); command->draw(4, static_cast(resource.vertexBuffer->getNumVertices()), 0, 0); } commands.add(command); @@ -176,7 +176,8 @@ void TextPass::createRenderPass() generalSet->updateSampler(1, glyphSampler); generalSet->writeChanges(); - pipelineLayout = graphics->createPipelineLayout(); + Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); + layoutRef = pipelineLayout; pipelineLayout->addDescriptorLayout(0, generalLayout); pipelineLayout->addDescriptorLayout(1, textureArrayLayout); pipelineLayout->addPushConstants({ @@ -193,7 +194,7 @@ void TextPass::createRenderPass() pipelineInfo.vertexShader = vertexShader; pipelineInfo.fragmentShader = fragmentShader; pipelineInfo.renderPass = renderPass; - pipelineInfo.pipelineLayout = pipelineLayout; + pipelineInfo.pipelineLayout = std::move(pipelineLayout); pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE; pipelineInfo.colorBlend.attachmentCount = 1; pipelineInfo.colorBlend.blendAttachments[0].blendEnable = true; @@ -206,7 +207,7 @@ void TextPass::createRenderPass() pipelineInfo.colorBlend.blendAttachments[0].alphaBlendOp = Gfx::SE_BLEND_OP_ADD; pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - pipeline = graphics->createGraphicsPipeline(pipelineInfo); + pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); } TextPass::FontData& TextPass::getFontData(PFontAsset font) { diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h index 8b54143..6c04f5c 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ b/src/Engine/Graphics/RenderPass/TextPass.h @@ -78,8 +78,8 @@ private: Gfx::OVertexDeclaration declaration; Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; - Gfx::OPipelineLayout pipelineLayout; - Gfx::OGraphicsPipeline pipeline; + Gfx::PPipelineLayout layoutRef; + Gfx::PGraphicsPipeline pipeline; Array texts; }; DEFINE_REF(TextPass); diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 41594fe..1fed55b 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -173,7 +173,7 @@ void UIPass::createRenderPass() descriptorSet->updateSampler(1, backgroundSampler); descriptorSet->writeChanges(); - pipelineLayout = graphics->createPipelineLayout(); + Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); pipelineLayout->addDescriptorLayout(0, descriptorLayout); pipelineLayout->create(); @@ -185,9 +185,9 @@ void UIPass::createRenderPass() pipelineInfo.vertexShader = vertexShader; pipelineInfo.fragmentShader = fragmentShader; pipelineInfo.renderPass = renderPass; - pipelineInfo.pipelineLayout = pipelineLayout; + pipelineInfo.pipelineLayout = std::move(pipelineLayout); pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE; pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; - pipeline = graphics->createGraphicsPipeline(pipelineInfo); + pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); } diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index e72e2b5..a1e10a2 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -34,8 +34,7 @@ private: Gfx::OVertexDeclaration declaration; Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; - Gfx::OPipelineLayout pipelineLayout; - Gfx::OGraphicsPipeline pipeline; + Gfx::PGraphicsPipeline pipeline; Array renderElements; Array usedTextures; diff --git a/src/Engine/Graphics/Resources.h b/src/Engine/Graphics/Resources.h index 6bcff4c..e952a35 100644 --- a/src/Engine/Graphics/Resources.h +++ b/src/Engine/Graphics/Resources.h @@ -4,6 +4,7 @@ #include "Containers/Array.h" #include "Containers/List.h" #include "Initializer.h" +#include "Descriptor.h" #include "CRC.h" #include @@ -92,22 +93,22 @@ DEFINE_REF(VertexDeclaration) class GraphicsPipeline { public: - GraphicsPipeline(PPipelineLayout layout) : layout(layout) {} + GraphicsPipeline(OPipelineLayout layout) : layout(std::move(layout)) {} virtual ~GraphicsPipeline(){} PPipelineLayout getPipelineLayout() const { return layout; } protected: - PPipelineLayout layout; + OPipelineLayout layout; }; DEFINE_REF(GraphicsPipeline) class ComputePipeline { public: - ComputePipeline(PPipelineLayout layout) : layout(layout) {} + ComputePipeline(OPipelineLayout layout) : layout(std::move(layout)) {} virtual ~ComputePipeline(){} PPipelineLayout getPipelineLayout() const { return layout; } protected: - PPipelineLayout layout; + OPipelineLayout layout; }; DEFINE_REF(ComputePipeline) diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp index a6e8d0e..663cbef 100644 --- a/src/Engine/Graphics/Shader.cpp +++ b/src/Engine/Graphics/Shader.cpp @@ -53,32 +53,28 @@ void ShaderCompiler::compile() ShaderPermutation permutation; for (const auto& [name, pass] : passes) { - permutation.hasFragment = pass.hasFragmentShader; - permutation.useMeshShading = pass.useMeshShading; - permutation.hasTaskShader = pass.hasTaskShader; std::strncpy(permutation.vertexMeshFile, pass.mainFile.c_str(), sizeof(permutation.vertexMeshFile)); if (pass.hasFragmentShader) { - std::strncpy(permutation.fragmentFile, pass.fragmentFile.c_str(), sizeof(permutation.fragmentFile)); + permutation.setFragmentFile(pass.fragmentFile); } if (pass.hasTaskShader) { - std::strncpy(permutation.taskFile, pass.taskFile.c_str(), sizeof(permutation.taskFile)); + permutation.setTaskFile(pass.taskFile); } for (const auto& [vdName, vd] : vertexData) { - std::strncpy(permutation.vertexDataName, vd->getTypeName().c_str(), sizeof(permutation.vertexDataName)); + permutation.setVertexData(vd->getTypeName()); if (pass.useMaterial) { for (const auto& [matName, mat] : materials) { - std::strncpy(permutation.materialName, matName.c_str(), sizeof(permutation.materialName)); + permutation.setMaterial(mat->getName()); createShaders(permutation); } } else { - std::memset(permutation.materialName, 0, sizeof(permutation.materialName)); createShaders(permutation); } } diff --git a/src/Engine/Graphics/Shader.h b/src/Engine/Graphics/Shader.h index a8543be..a41d67f 100644 --- a/src/Engine/Graphics/Shader.h +++ b/src/Engine/Graphics/Shader.h @@ -49,8 +49,8 @@ public: }; DEFINE_REF(ComputeShader) - //Uniquely identifies a permutation of shaders - //using the type parameters used to generate it +//Uniquely identifies a permutation of shaders +//using the type parameters used to generate it struct ShaderPermutation { char taskFile[32]; @@ -61,11 +61,47 @@ struct ShaderPermutation uint8 hasFragment : 1; uint8 useMeshShading : 1; uint8 hasTaskShader : 1; + uint8 useMaterial : 1; //TODO: lightmapping etc ShaderPermutation() { std::memset(this, 0, sizeof(ShaderPermutation)); } + void setTaskFile(std::string_view name) + { + std::memset(taskFile, 0, sizeof(taskFile)); + hasTaskShader = 1; + std::strncpy(taskFile, name.data(), 32); + } + void setVertexFile(std::string_view name) + { + std::memset(vertexMeshFile, 0, sizeof(vertexMeshFile)); + useMeshShading = 0; + std::strncpy(vertexMeshFile, name.data(), 32); + } + void setMeshFile(std::string_view name) + { + std::memset(vertexMeshFile, 0, sizeof(vertexMeshFile)); + useMeshShading = 1; + std::strncpy(vertexMeshFile, name.data(), 32); + } + void setFragmentFile(std::string_view name) + { + std::memset(fragmentFile, 0, sizeof(fragmentFile)); + hasFragment = 1; + std::strncpy(fragmentFile, name.data(), 32); + } + void setVertexData(std::string_view name) + { + std::memset(vertexDataName, 0, sizeof(vertexDataName)); + std::strncpy(vertexDataName, name.data(), 32); + } + void setMaterial(std::string_view name) + { + std::memset(materialName, 0, sizeof(materialName)); + useMaterial = 1; + std::strncpy(materialName, name.data(), 32); + } }; //Hashed ShaderPermutation for fast lookup struct PermutationId diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index c18c4d8..91950bd 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -33,6 +33,7 @@ void VertexData::updateMesh(const Component::Transform& transform, PMesh mesh) }, .indexBuffer = mesh->indexBuffer, }); + matInstanceData.numMeshes += meshData[mesh->id].size(); } void VertexData::loadMesh(MeshId id, Array loadedMeshlets) @@ -143,6 +144,7 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) { MeshId res{ idCounter++ }; meshOffsets[res] = head; + meshVertexCounts[res] = numVertices; head += numVertices; if (head > verticesAllocated) { @@ -152,11 +154,16 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) return res; } -uint32 VertexData::getMeshOffset(MeshId id) +uint64 VertexData::getMeshOffset(MeshId id) { return meshOffsets[id]; } +uint64 VertexData::getMeshVertexCount(MeshId id) +{ + return meshVertexCounts[id]; +} + List vertexDataList; List VertexData::getList() diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 907f5c9..f5c81c0 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -65,7 +65,8 @@ public: void loadMesh(MeshId id, Array meshlets); void createDescriptors(); MeshId allocateVertexData(uint64 numVertices); - uint32 getMeshOffset(MeshId id); + uint64 getMeshOffset(MeshId id); + uint64 getMeshVertexCount(MeshId id); virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) = 0; virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) = 0; virtual void bindBuffers(Gfx::PRenderCommand command) = 0; @@ -100,6 +101,7 @@ protected: Map materialData; Map> meshData; Map meshOffsets; + Map meshVertexCounts; Array meshlets; Array primitiveIndices; Array vertexIndices; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index e97b1f1..4fd3391 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -191,18 +191,18 @@ Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo) return std::move(shader); } -Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) +Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) { - return pipelineCache->createPipeline(createInfo); + return pipelineCache->createPipeline(std::move(createInfo)); } -Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) +Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) { - return pipelineCache->createPipeline(createInfo); + return pipelineCache->createPipeline(std::move(createInfo)); } -Gfx::OComputePipeline Graphics::createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) +Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) { - return pipelineCache->createPipeline(createInfo); + return pipelineCache->createPipeline(std::move(createInfo)); } Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo) diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index 8181ed3..653e87a 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -64,9 +64,9 @@ public: virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::OTaskShader createTaskShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::OMeshShader createMeshShader(const ShaderCreateInfo& createInfo) override; - virtual Gfx::OGraphicsPipeline createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo) override; - virtual Gfx::OGraphicsPipeline createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo) override; - virtual Gfx::OComputePipeline createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) override; + virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) override; + virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override; virtual Gfx::OSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override; diff --git a/src/Engine/Graphics/Vulkan/Pipeline.cpp b/src/Engine/Graphics/Vulkan/Pipeline.cpp index c8a0b0e..099e7a2 100644 --- a/src/Engine/Graphics/Vulkan/Pipeline.cpp +++ b/src/Engine/Graphics/Vulkan/Pipeline.cpp @@ -5,8 +5,8 @@ using namespace Seele; using namespace Seele::Vulkan; -GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout) - : Gfx::GraphicsPipeline(pipelineLayout) +GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, Gfx::OPipelineLayout pipelineLayout) + : Gfx::GraphicsPipeline(std::move(pipelineLayout)) , graphics(graphics) , pipeline(handle) { @@ -23,11 +23,11 @@ void GraphicsPipeline::bind(VkCommandBuffer handle) VkPipelineLayout GraphicsPipeline::getLayout() const { - return layout.cast()->getHandle(); + return Gfx::PPipelineLayout(layout).cast()->getHandle(); } -ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout) - : Gfx::ComputePipeline(pipelineLayout) +ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::OPipelineLayout pipelineLayout) + : Gfx::ComputePipeline(std::move(pipelineLayout)) , graphics(graphics) , pipeline(handle) { @@ -45,5 +45,5 @@ void ComputePipeline::bind(VkCommandBuffer handle) VkPipelineLayout ComputePipeline::getLayout() const { - return layout.cast()->getHandle(); + return Gfx::PPipelineLayout(layout).cast()->getHandle(); } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Pipeline.h b/src/Engine/Graphics/Vulkan/Pipeline.h index ba35967..4edf9e7 100644 --- a/src/Engine/Graphics/Vulkan/Pipeline.h +++ b/src/Engine/Graphics/Vulkan/Pipeline.h @@ -11,7 +11,7 @@ DECLARE_REF(Graphics) class GraphicsPipeline : public Gfx::GraphicsPipeline { public: - GraphicsPipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout); + GraphicsPipeline(PGraphics graphics, VkPipeline handle, Gfx::OPipelineLayout pipelineLayout); virtual ~GraphicsPipeline(); void bind(VkCommandBuffer handle); VkPipelineLayout getLayout() const; @@ -23,7 +23,7 @@ DEFINE_REF(GraphicsPipeline) class ComputePipeline : public Gfx::ComputePipeline { public: - ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout); + ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::OPipelineLayout pipelineLayout); virtual ~ComputePipeline(); void bind(VkCommandBuffer handle); VkPipelineLayout getLayout() const; diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index 09b53a5..7966f4b 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -48,32 +48,10 @@ PipelineCache::~PipelineCache() std::cout << "Written " << cacheSize << " bytes to cache" << std::endl; } -OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo) +PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gfxInfo) { - uint32 stageCount = 0; - - VkPipelineShaderStageCreateInfo stageInfos[2]; - std::memset(stageInfos, 0, sizeof(stageInfos)); - - PVertexShader vertexShader = gfxInfo.vertexShader.cast(); - stageInfos[stageCount++] = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = vertexShader->getModuleHandle(), - .pName = vertexShader->getEntryPointName(), - }; - - if(gfxInfo.fragmentShader != nullptr) - { - PFragmentShader fragment = gfxInfo.fragmentShader.cast(); - - stageInfos[stageCount++] = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = fragment->getModuleHandle(), - .pName = fragment->getEntryPointName(), - }; - } + PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast(); + uint32 hash = layout->getHash(); VkPipelineVertexInputStateCreateInfo vertexInput = init::PipelineVertexInputStateCreateInfo(); @@ -107,19 +85,47 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI vertexInput.pVertexBindingDescriptions = bindings.data(); vertexInput.vertexBindingDescriptionCount = bindings.size(); } + hash = CRC::Calculate(bindings.data(), bindings.size() * sizeof(VkVertexInputBindingDescription), CRC::CRC_32(), hash); + hash = CRC::Calculate(attributes.data(), attributes.size() * sizeof(VkVertexInputAttributeDescription), CRC::CRC_32(), hash); + uint32 stageCount = 0; + VkPipelineShaderStageCreateInfo stageInfos[2]; + std::memset(stageInfos, 0, sizeof(stageInfos)); + + PVertexShader vertexShader = gfxInfo.vertexShader.cast(); + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = vertexShader->getModuleHandle(), + .pName = vertexShader->getEntryPointName(), + }; + + if (gfxInfo.fragmentShader != nullptr) + { + PFragmentShader fragment = gfxInfo.fragmentShader.cast(); + + stageInfos[stageCount++] = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = fragment->getModuleHandle(), + .pName = fragment->getEntryPointName(), + }; + } + hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash); VkPipelineInputAssemblyStateCreateInfo assemblyInfo = init::PipelineInputAssemblyStateCreateInfo( cast(gfxInfo.topology), 0, false ); + hash = CRC::Calculate(&assemblyInfo, sizeof(assemblyInfo), CRC::CRC_32(), hash); VkPipelineViewportStateCreateInfo viewportInfo = init::PipelineViewportStateCreateInfo( 1, 1, 0 ); + hash = CRC::Calculate(&viewportInfo, sizeof(viewportInfo), CRC::CRC_32(), hash); VkPipelineRasterizationStateCreateInfo rasterizationState = init::PipelineRasterizationStateCreateInfo( cast(gfxInfo.rasterizationState.polygonMode), @@ -134,6 +140,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable; rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth; rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable; + hash = CRC::Calculate(&rasterizationState, sizeof(rasterizationState), CRC::CRC_32(), hash); VkPipelineMultisampleStateCreateInfo multisampleState = init::PipelineMultisampleStateCreateInfo( @@ -143,6 +150,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable; multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading; multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable; + hash = CRC::Calculate(&multisampleState, sizeof(multisampleState), CRC::CRC_32(), hash); VkPipelineDepthStencilStateCreateInfo depthStencilState = init::PipelineDepthStencilStateCreateInfo( @@ -150,6 +158,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI gfxInfo.depthStencilState.depthWriteEnable, cast(gfxInfo.depthStencilState.depthCompareOp) ); + hash = CRC::Calculate(&depthStencilState, sizeof(depthStencilState), CRC::CRC_32(), hash); const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments; Array blendAttachments(colorAttachments.size()); @@ -167,6 +176,8 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI .colorWriteMask = attachment.colorWriteMask, }; } + hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash); + VkPipelineColorBlendStateCreateInfo blendState = init::PipelineColorBlendStateCreateInfo( (uint32)blendAttachments.size(), @@ -180,6 +191,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI StaticArray dynamicEnabled; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR; + hash = CRC::Calculate(dynamicEnabled.data(), dynamicEnabled.size() * sizeof(VkDynamicState), CRC::CRC_32(), hash); VkPipelineDynamicStateCreateInfo dynamicState = init::PipelineDynamicStateCreateInfo( @@ -188,8 +200,10 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI 0 ); - PPipelineLayout layout = gfxInfo.pipelineLayout.cast(); - + if (graphicsPipelines.contains(hash)) + { + return graphicsPipelines[hash]; + } VkPipeline pipelineHandle; VkGraphicsPipelineCreateInfo createInfo = { @@ -216,14 +230,17 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); std::cout << "Gfx creation time: " << delta << std::endl; - - OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); + OGraphicsPipeline pipeline = new GraphicsPipeline(graphics, pipelineHandle, std::move(gfxInfo.pipelineLayout)); + PGraphicsPipeline result = pipeline; + graphicsPipelines[hash] = std::move(pipeline); return result; } -OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo) +PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxInfo) { + PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast(); + uint32 hash = layout->getHash(); uint32 stageCount = 0; VkPipelineShaderStageCreateInfo stageInfos[3]; @@ -259,12 +276,16 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf .pName = fragment->getEntryPointName(), }; } + hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash); + VkPipelineViewportStateCreateInfo viewportInfo = init::PipelineViewportStateCreateInfo( 1, 1, 0 ); + hash = CRC::Calculate(&viewportInfo, sizeof(viewportInfo), CRC::CRC_32(), hash); + VkPipelineRasterizationStateCreateInfo rasterizationState = init::PipelineRasterizationStateCreateInfo( cast(gfxInfo.rasterizationState.polygonMode), @@ -279,6 +300,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf rasterizationState.depthClampEnable = gfxInfo.rasterizationState.depthClampEnable; rasterizationState.lineWidth = gfxInfo.rasterizationState.lineWidth; rasterizationState.rasterizerDiscardEnable = gfxInfo.rasterizationState.rasterizerDiscardEnable; + hash = CRC::Calculate(&rasterizationState, sizeof(rasterizationState), CRC::CRC_32(), hash); VkPipelineMultisampleStateCreateInfo multisampleState = init::PipelineMultisampleStateCreateInfo( @@ -288,6 +310,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf multisampleState.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable; multisampleState.minSampleShading = gfxInfo.multisampleState.minSampleShading; multisampleState.sampleShadingEnable = gfxInfo.multisampleState.sampleShadingEnable; + hash = CRC::Calculate(&multisampleState, sizeof(multisampleState), CRC::CRC_32(), hash); VkPipelineDepthStencilStateCreateInfo depthStencilState = init::PipelineDepthStencilStateCreateInfo( @@ -295,6 +318,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf gfxInfo.depthStencilState.depthWriteEnable, cast(gfxInfo.depthStencilState.depthCompareOp) ); + hash = CRC::Calculate(&depthStencilState, sizeof(depthStencilState), CRC::CRC_32(), hash); const auto& colorAttachments = gfxInfo.renderPass->getLayout()->colorAttachments; Array blendAttachments(colorAttachments.size()); @@ -312,6 +336,8 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf .colorWriteMask = attachment.colorWriteMask, }; } + hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash); + VkPipelineColorBlendStateCreateInfo blendState = init::PipelineColorBlendStateCreateInfo( (uint32)blendAttachments.size(), @@ -325,6 +351,7 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf StaticArray dynamicEnabled; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR; + hash = CRC::Calculate(dynamicEnabled.data(), dynamicEnabled.size() * sizeof(VkDynamicState), CRC::CRC_32(), hash); VkPipelineDynamicStateCreateInfo dynamicState = init::PipelineDynamicStateCreateInfo( @@ -333,8 +360,11 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf 0 ); - PPipelineLayout layout = gfxInfo.pipelineLayout.cast(); - + if (graphicsPipelines.contains(hash)) + { + std::cout << "Caching pipeline" << std::endl; + return graphicsPipelines[hash]; + } VkPipeline pipelineHandle; VkGraphicsPipelineCreateInfo createInfo = { @@ -361,16 +391,20 @@ OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); std::cout << "Gfx creation time: " << delta << std::endl; - OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout); + OGraphicsPipeline pipeline = new GraphicsPipeline(graphics, pipelineHandle, std::move(gfxInfo.pipelineLayout)); + PGraphicsPipeline result = pipeline; + graphicsPipelines[hash] = std::move(pipeline); return result; } -OComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo) +PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo computeInfo) { - auto layout = computeInfo.pipelineLayout.cast(); + PPipelineLayout layout = Gfx::PPipelineLayout(computeInfo.pipelineLayout).cast(); auto computeStage = computeInfo.computeShader.cast(); + uint32 hash = layout->getHash(); + VkComputePipelineCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, .pNext = 0, @@ -383,6 +417,7 @@ OComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateI .basePipelineHandle = VK_NULL_HANDLE, .basePipelineIndex = 0, }; + hash = CRC::Calculate(&createInfo, sizeof(createInfo), CRC::CRC_32(), hash); VkPipeline pipelineHandle; auto beginTime = std::chrono::high_resolution_clock::now(); @@ -390,6 +425,9 @@ OComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateI auto endTime = std::chrono::high_resolution_clock::now(); int64 delta = std::chrono::duration_cast(endTime - beginTime).count(); std::cout << "Compute creation time: " << delta << std::endl; - OComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout); + + OComputePipeline pipeline = new ComputePipeline(graphics, pipelineHandle, std::move(computeInfo.pipelineLayout)); + PComputePipeline result = pipeline; + graphicsPipelines[hash] = std::move(pipeline); return result; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.h b/src/Engine/Graphics/Vulkan/PipelineCache.h index 98dbc2d..58b6e2d 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.h +++ b/src/Engine/Graphics/Vulkan/PipelineCache.h @@ -10,10 +10,12 @@ class PipelineCache public: PipelineCache(PGraphics graphics, const std::string& cacheFilePath); ~PipelineCache(); - OGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo); - OGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo); - OComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo); + PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo); + PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo); + PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo); private: + Map graphicsPipelines; + Map computePipelines; VkPipelineCache cache; PGraphics graphics; std::string cacheFile; diff --git a/src/Engine/Graphics/Vulkan/Shader.cpp b/src/Engine/Graphics/Vulkan/Shader.cpp index d37b159..2862595 100644 --- a/src/Engine/Graphics/Vulkan/Shader.cpp +++ b/src/Engine/Graphics/Vulkan/Shader.cpp @@ -63,17 +63,19 @@ void Shader::create(const ShaderCreateInfo& createInfo) Slang::ComPtr diagnostics; Array modules; Slang::ComPtr entrypoint; - - for (auto moduleName : createInfo.additionalModules) + slang::IModule* mainModule = nullptr; + for (const auto& moduleName : createInfo.additionalModules) { modules.add(session->loadModule(moduleName.c_str(), diagnostics.writeRef())); + if (moduleName == createInfo.mainModule) + { + mainModule = (slang::IModule*)modules.back(); + } if(diagnostics) { std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; } } - slang::IModule* mainModule = session->loadModule(createInfo.mainModule.c_str(), diagnostics.writeRef()); - modules.add(mainModule); if(diagnostics) { @@ -143,13 +145,14 @@ void Shader::create(const ShaderCreateInfo& createInfo) } VkShaderModuleCreateInfo moduleInfo; - moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - moduleInfo.pNext = nullptr; - moduleInfo.flags = 0; - moduleInfo.codeSize = kernelBlob->getBufferSize(); - moduleInfo.pCode = (uint32_t*)kernelBlob->getBufferPointer(); - VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module)); + moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + moduleInfo.pNext = nullptr; + moduleInfo.flags = 0; + moduleInfo.codeSize = kernelBlob->getBufferSize(); + moduleInfo.pCode = (uint32_t*)kernelBlob->getBufferPointer(); + VK_CHECK(vkCreateShaderModule(graphics->getDevice(), &moduleInfo, nullptr, &module)); hash = CRC::Calculate(entryPointName.data(), entryPointName.size(), CRC::CRC_32()); hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32(), hash); + std::cout << "Creating Shader" << std::endl; } \ No newline at end of file