diff --git a/res/shaders/BasePass.slang b/res/shaders/BasePass.slang index 0bffada..b48756c 100644 --- a/res/shaders/BasePass.slang +++ b/res/shaders/BasePass.slang @@ -12,8 +12,14 @@ struct LightCullingData layout(set=5) ParameterBlock pLightCullingData; +struct FragmentOutput +{ + float4 color : SV_Target0; + uint meshletId : SV_Target1; +}; + [shader("pixel")] -float4 fragmentMain(in FragmentParameter params) : SV_Target +FragmentOutput fragmentMain(in FragmentParameter params) { LightingParameter lightingParams = params.getLightingParameter(); MaterialParameter materialParams = params.getMaterialParameter(); @@ -35,5 +41,8 @@ float4 fragmentMain(in FragmentParameter params) : SV_Target // gamma correction result = result / (result + float3(1.0)); result = pow(result, float3(1.0/2.2)); - return float4(result, 1.0f); + FragmentOutput output; + output.color = float4(result, 1.0f); + output.meshletId = params.meshletId; + return output; } diff --git a/res/shaders/MeshletPass.slang b/res/shaders/MeshletPass.slang index 1f79e90..49ef1a5 100644 --- a/res/shaders/MeshletPass.slang +++ b/res/shaders/MeshletPass.slang @@ -94,7 +94,8 @@ void meshMain( uint v = min(i, m.vertexCount - 1); { uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v]; - VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex); + VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex); + attr.meshletId = -1; vertices[v] = attr.getParameter(inst.transformMatrix); //vertices[v].vertexColor = m.color; } diff --git a/res/shaders/StaticMeshletPass.slang b/res/shaders/StaticMeshletPass.slang index 9e2eecc..63b2048 100644 --- a/res/shaders/StaticMeshletPass.slang +++ b/res/shaders/StaticMeshletPass.slang @@ -9,6 +9,12 @@ struct PrimitiveAttributes uint cull: SV_CullPrimitive; }; +struct CulledMeshletList +{ + StructuredBuffer meshletIndices; +}; +ParameterBlock pCullingList; + [numthreads(MESH_GROUP_SIZE, 1, 1)] [outputtopology("triangle")] [shader("mesh")] @@ -18,7 +24,8 @@ void meshMain( out vertices FragmentParameter vertices[MAX_VERTICES], out indices uint3 indices[MAX_PRIMITIVES] ){ - MeshletDescription m = pScene.meshletInfos[groupID]; + uint meshletIndex = pCullingList.meshletIndices[groupID]; + MeshletDescription m = pScene.meshletInfos[meshletIndex]; SetMeshOutputCounts(m.vertexCount, m.primitiveCount); for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE) @@ -36,7 +43,8 @@ void meshMain( uint v = min(i, m.vertexCount - 1); { uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v]; - VertexAttributes attr = pVertexData.getAttributes(md.indicesOffset + vertexIndex); + VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex); + attr.meshletId = meshletIndex; vertices[v] = attr.getParameter(float4x4(1.0)); } } diff --git a/res/shaders/lib/MaterialParameter.slang b/res/shaders/lib/MaterialParameter.slang index d1bbb82..b35d01a 100644 --- a/res/shaders/lib/MaterialParameter.slang +++ b/res/shaders/lib/MaterialParameter.slang @@ -25,6 +25,7 @@ struct FragmentParameter float3 biTangent_WS : TANGENT1; float3 position_WS : POSITION2; float3 vertexColor : COLOR0; + uint meshletId : POSITION3; float2 texCoords[MAX_TEXCOORDS] : TEXCOORD0; MaterialParameter getMaterialParameter() { @@ -55,6 +56,7 @@ struct VertexAttributes float3 tangent_MS; float3 biTangent_MS; float3 vertexColor; + uint meshletId; float2 texCoords[MAX_TEXCOORDS]; FragmentParameter getParameter(float4x4 transformMatrix) { @@ -73,6 +75,7 @@ struct VertexAttributes result.position_WS = worldPos.xyz; result.position_CS = clipPos; result.vertexColor = vertexColor; + result.meshletId = meshletId; for(uint i = 0; i < MAX_TEXCOORDS; ++i) { result.texCoords[i] = texCoords[i]; diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index 7d98e84..a9f1587 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -8,7 +8,7 @@ struct MeshletDescription uint32_t vertexOffset; uint32_t primitiveOffset; float3 color; - float pad; + uint32_t indicesOffset; }; struct MeshData @@ -18,8 +18,6 @@ struct MeshData uint32_t meshletOffset; uint32_t firstIndex; uint32_t numIndices; - uint32_t indicesOffset; - uint32_t pad0[3]; }; static const uint MAX_VERTICES = 256; diff --git a/src/Engine/Graphics/CMakeLists.txt b/src/Engine/Graphics/CMakeLists.txt index 930a40f..5fdd7c2 100644 --- a/src/Engine/Graphics/CMakeLists.txt +++ b/src/Engine/Graphics/CMakeLists.txt @@ -12,7 +12,6 @@ target_sources(Engine Graphics.h Graphics.cpp Initializer.h - Initializer.cpp Mesh.h Mesh.cpp Meshlet.h diff --git a/src/Engine/Graphics/Command.h b/src/Engine/Graphics/Command.h index c2cf7c8..2f5c812 100644 --- a/src/Engine/Graphics/Command.h +++ b/src/Engine/Graphics/Command.h @@ -22,6 +22,7 @@ public: virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0; virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) = 0; virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) = 0; + virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) = 0; std::string name; }; DEFINE_REF(RenderCommand) diff --git a/src/Engine/Graphics/Initializer.cpp b/src/Engine/Graphics/Initializer.cpp deleted file mode 100644 index 79edf0b..0000000 --- a/src/Engine/Graphics/Initializer.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "Initializer.h" -#include "Descriptor.h" - -using namespace Seele; -using namespace Seele::Gfx; - -LegacyPipelineCreateInfo::LegacyPipelineCreateInfo() - : topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) - , multisampleState(MultisampleState{ - .samples = 1, - }) - , rasterizationState(RasterizationState{ - .polygonMode = Gfx::SE_POLYGON_MODE_FILL, - .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, - .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE, - }) - , depthStencilState(DepthStencilState{ - .depthTestEnable = true, - .depthWriteEnable = true, - .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL, - .stencilTestEnable = false, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f, - }) - , colorBlend(ColorBlendState{ - .logicOpEnable = false, - .attachmentCount = 0, - .blendAttachments = { - ColorBlendState::BlendAttachment{ - .colorWriteMask = - Gfx::SE_COLOR_COMPONENT_R_BIT | - Gfx::SE_COLOR_COMPONENT_G_BIT | - Gfx::SE_COLOR_COMPONENT_B_BIT | - Gfx::SE_COLOR_COMPONENT_A_BIT, - } - }, - .blendConstants = { - 1.0f, - 1.0f, - 1.0f, - 1.0f, - }, - }) -{ -} - -LegacyPipelineCreateInfo::~LegacyPipelineCreateInfo() -{ -} - - -MeshPipelineCreateInfo::MeshPipelineCreateInfo() - : multisampleState(MultisampleState{ - .samples = 1, - }) - , rasterizationState(RasterizationState{ - .polygonMode = Gfx::SE_POLYGON_MODE_FILL, - .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, - .frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE, - }) - , depthStencilState(DepthStencilState{ - .depthTestEnable = true, - .depthWriteEnable = true, - .depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL, - .stencilTestEnable = false, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f, - }) - , colorBlend(ColorBlendState{ - .logicOpEnable = false, - .attachmentCount = 0, - .blendAttachments = { - ColorBlendState::BlendAttachment{ - .colorWriteMask = - Gfx::SE_COLOR_COMPONENT_R_BIT | - Gfx::SE_COLOR_COMPONENT_G_BIT | - Gfx::SE_COLOR_COMPONENT_B_BIT | - Gfx::SE_COLOR_COMPONENT_A_BIT, - } - }, - .blendConstants = { - 1.0f, - 1.0f, - 1.0f, - 1.0f, - }, - }) -{ -} - -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 95e1202..a7da9a7 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -5,250 +5,244 @@ namespace Seele { -struct GraphicsInitializer -{ - const char *applicationName; - const char *engineName; - const char *windowLayoutFile; - /** - * layers defines the enabled Vulkan layers used in the instance, - * if ENABLE_VALIDATION is defined, standard validation is already enabled - * not yet implemented - */ - Array layers; - Array instanceExtensions; - Array deviceExtensions; - - void *windowHandle; - GraphicsInitializer() - : applicationName("SeeleEngine") - , engineName("SeeleEngine") - , windowLayoutFile(nullptr) - , layers{"VK_LAYER_LUNARG_monitor"} - , instanceExtensions{} - , deviceExtensions{"VK_KHR_swapchain"} - , windowHandle(nullptr) + struct GraphicsInitializer { - } -}; -struct WindowCreateInfo -{ - int32 width; - int32 height; - const char *title; - Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM; - void *windowHandle; -}; -struct ViewportCreateInfo -{ - URect dimensions; - float fieldOfView = 1.222f; // 70 deg - Gfx::SeSampleCountFlags numSamples; -}; -// doesnt own the data, only proxy it -struct DataSource -{ - uint64 size = 0; - uint64 offset = 0; - uint8 *data = nullptr; - Gfx::QueueType owner = Gfx::QueueType::GRAPHICS; -}; -struct TextureCreateInfo -{ - DataSource sourceData = DataSource(); - Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT; - uint32 width = 1; - uint32 height = 1; - uint32 depth = 1; - uint32 mipLevels = 1; - uint32 layers = 1; - uint32 elements = 1; - uint32 samples = 1; - Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; - Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - std::string name; -}; -struct SamplerCreateInfo -{ - Gfx::SeSamplerCreateFlags flags; - Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR; - Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR; - Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR; - Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; - Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; - Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; - float mipLodBias = 0.0f; - uint32 anisotropyEnable = 0; - float maxAnisotropy = 0.0f; - uint32 compareEnable = 0; - Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER; - float minLod = 0.0f; - float maxLod = 0.0f; - Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK; - uint32 unnormalizedCoordinates = 0; - std::string name; -}; -struct VertexBufferCreateInfo -{ - DataSource sourceData = DataSource(); - // bytes per vertex - uint32 vertexSize = 0; - uint32 numVertices = 0; - std::string name = ""; -}; -struct IndexBufferCreateInfo -{ - DataSource sourceData = DataSource(); - Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16; - std::string name = ""; -}; -struct UniformBufferCreateInfo -{ - DataSource sourceData = DataSource(); - uint8 dynamic = 0; - std::string name = ""; -}; -struct ShaderBufferCreateInfo -{ - DataSource sourceData = DataSource(); - uint64 numElements = 1; - uint8 dynamic = 0; - std::string name = ""; -}; -DECLARE_NAME_REF(Gfx, PipelineLayout) -struct ShaderCreateInfo -{ - std::string name; // Debug info - std::string mainModule; - Array additionalModules; - std::string entryPoint; - Array> typeParameter; - Map defines; - Gfx::PPipelineLayout rootSignature; -}; -struct VertexInputBinding -{ - uint32 binding; - uint32 stride; - Gfx::SeVertexInputRate inputRate; -}; -struct VertexInputAttribute -{ - uint32 location; - uint32 binding; - Gfx::SeFormat format; - uint32 offset; -}; -struct VertexInputStateCreateInfo -{ - Array bindings; - Array attributes; -}; -namespace Gfx -{ -struct SePushConstantRange -{ - SeShaderStageFlags stageFlags; - uint32 offset; - uint32 size; -}; -struct RasterizationState -{ - uint32 depthClampEnable = 0; - uint32 rasterizerDiscardEnable = 0; - SePolygonMode polygonMode; - SeCullModeFlags cullMode; - SeFrontFace frontFace; - uint32 depthBiasEnable = 0; - float depthBiasConstantFactor = 0; - float depthBiasClamp = 0; - float depthBiasSlopeFactor = 0; - float lineWidth = 1.0; -}; -struct MultisampleState -{ - SeSampleCountFlags samples = 1; - uint32 sampleShadingEnable = 0; - float minSampleShading = 1; - uint8 alphaCoverageEnable = 0; - uint8 alphaToOneEnable = 0; -}; -struct DepthStencilState -{ - uint32 depthTestEnable = 0; - uint32 depthWriteEnable = 0; - SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_LESS; - uint32 depthBoundsTestEnable = 0; - uint32 stencilTestEnable = 0; - SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO; - SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO; - float minDepthBounds; - float maxDepthBounds; -}; -struct ColorBlendState -{ - struct BlendAttachment - { - uint32 blendEnable = 0; - SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD; - SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; - SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD; - SeColorComponentFlags colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT; + const char* applicationName; + const char* engineName; + const char* windowLayoutFile; + /** + * layers defines the enabled Vulkan layers used in the instance, + * if ENABLE_VALIDATION is defined, standard validation is already enabled + * not yet implemented + */ + Array layers; + Array instanceExtensions; + Array deviceExtensions; + + void* windowHandle; + GraphicsInitializer() + : applicationName("SeeleEngine") + , engineName("SeeleEngine") + , windowLayoutFile(nullptr) + , layers{ "VK_LAYER_LUNARG_monitor" } + , instanceExtensions{} + , deviceExtensions{ "VK_KHR_swapchain" } + , windowHandle(nullptr) + { + } }; - uint32 logicOpEnable; - SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR; - uint32 attachmentCount; - StaticArray blendAttachments; - StaticArray blendConstants; -}; + struct WindowCreateInfo + { + int32 width; + int32 height; + const char* title; + Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM; + void* windowHandle; + }; + struct ViewportCreateInfo + { + URect dimensions; + float fieldOfView = 1.222f; // 70 deg + Gfx::SeSampleCountFlags numSamples; + }; + // doesnt own the data, only proxy it + struct DataSource + { + uint64 size = 0; + uint64 offset = 0; + uint8* data = nullptr; + Gfx::QueueType owner = Gfx::QueueType::GRAPHICS; + }; + struct TextureCreateInfo + { + DataSource sourceData = DataSource(); + Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT; + uint32 width = 1; + uint32 height = 1; + uint32 depth = 1; + uint32 mipLevels = 1; + uint32 layers = 1; + uint32 elements = 1; + uint32 samples = 1; + Gfx::SeImageUsageFlags usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT; + Gfx::SeMemoryPropertyFlags memoryProps = Gfx::SE_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + std::string name; + }; + struct SamplerCreateInfo + { + Gfx::SeSamplerCreateFlags flags; + Gfx::SeFilter magFilter = Gfx::SE_FILTER_LINEAR; + Gfx::SeFilter minFilter = Gfx::SE_FILTER_LINEAR; + Gfx::SeSamplerMipmapMode mipmapMode = Gfx::SE_SAMPLER_MIPMAP_MODE_LINEAR; + Gfx::SeSamplerAddressMode addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; + Gfx::SeSamplerAddressMode addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; + Gfx::SeSamplerAddressMode addressModeW = Gfx::SE_SAMPLER_ADDRESS_MODE_REPEAT; + float mipLodBias = 0.0f; + uint32 anisotropyEnable = 0; + float maxAnisotropy = 0.0f; + uint32 compareEnable = 0; + Gfx::SeCompareOp compareOp = Gfx::SE_COMPARE_OP_NEVER; + float minLod = 0.0f; + float maxLod = 0.0f; + Gfx::SeBorderColor borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK; + uint32 unnormalizedCoordinates = 0; + std::string name; + }; + struct VertexBufferCreateInfo + { + DataSource sourceData = DataSource(); + // bytes per vertex + uint32 vertexSize = 0; + uint32 numVertices = 0; + std::string name = ""; + }; + struct IndexBufferCreateInfo + { + DataSource sourceData = DataSource(); + Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16; + std::string name = ""; + }; + struct UniformBufferCreateInfo + { + DataSource sourceData = DataSource(); + uint8 dynamic = 0; + std::string name = ""; + }; + struct ShaderBufferCreateInfo + { + DataSource sourceData = DataSource(); + uint64 numElements = 1; + uint8 dynamic = 0; + std::string name = ""; + }; + DECLARE_NAME_REF(Gfx, PipelineLayout) + struct ShaderCreateInfo + { + std::string name; // Debug info + std::string mainModule; + Array additionalModules; + std::string entryPoint; + Array> typeParameter; + Map defines; + Gfx::PPipelineLayout rootSignature; + }; + struct VertexInputBinding + { + uint32 binding; + uint32 stride; + Gfx::SeVertexInputRate inputRate; + }; + struct VertexInputAttribute + { + uint32 location; + uint32 binding; + Gfx::SeFormat format; + uint32 offset; + }; + struct VertexInputStateCreateInfo + { + Array bindings; + Array attributes; + }; + namespace Gfx + { + struct SePushConstantRange + { + SeShaderStageFlags stageFlags; + uint32 offset; + uint32 size; + }; + struct RasterizationState + { + uint32 depthClampEnable = 0; + uint32 rasterizerDiscardEnable = 0; + SePolygonMode polygonMode = Gfx::SE_POLYGON_MODE_FILL; + SeCullModeFlags cullMode = Gfx::SE_CULL_MODE_BACK_BIT; + SeFrontFace frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE; + uint32 depthBiasEnable = 0; + float depthBiasConstantFactor = 0; + float depthBiasClamp = 0; + float depthBiasSlopeFactor = 0; + float lineWidth = 1.0; + }; + struct MultisampleState + { + SeSampleCountFlags samples = 1; + uint32 sampleShadingEnable = 0; + float minSampleShading = 1; + uint8 alphaCoverageEnable = 0; + uint8 alphaToOneEnable = 0; + }; + struct DepthStencilState + { + uint32 depthTestEnable = 1; + uint32 depthWriteEnable = 1; + SeCompareOp depthCompareOp = Gfx::SE_COMPARE_OP_GREATER; + uint32 depthBoundsTestEnable = 0; + uint32 stencilTestEnable = 0; + SeStencilOp front = Gfx::SE_STENCIL_OP_ZERO; + SeStencilOp back = Gfx::SE_STENCIL_OP_ZERO; + float minDepthBounds = 0.0f; + float maxDepthBounds = 1.0f; + }; + struct ColorBlendState + { + struct BlendAttachment + { + uint32 blendEnable = 0; + SeBlendFactor srcColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendFactor dstColorBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendOp colorBlendOp = Gfx::SE_BLEND_OP_ADD; + SeBlendFactor srcAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendFactor dstAlphaBlendFactor = Gfx::SE_BLEND_FACTOR_SRC_ALPHA; + SeBlendOp alphaBlendOp = Gfx::SE_BLEND_OP_ADD; + SeColorComponentFlags colorWriteMask = Gfx::SE_COLOR_COMPONENT_R_BIT | Gfx::SE_COLOR_COMPONENT_G_BIT | Gfx::SE_COLOR_COMPONENT_B_BIT | Gfx::SE_COLOR_COMPONENT_A_BIT; + }; + uint32 logicOpEnable = 0; + SeLogicOp logicOp = Gfx::SE_LOGIC_OP_OR; + uint32 attachmentCount = 0; + StaticArray blendAttachments; + StaticArray blendConstants = { 1.0f, 1.0f, 1.0f, 1.0f, }; + }; -DECLARE_REF(VertexInput) -DECLARE_REF(VertexShader) -DECLARE_REF(TaskShader) -DECLARE_REF(MeshShader) -DECLARE_REF(FragmentShader) -DECLARE_REF(ComputeShader) -DECLARE_REF(RenderPass) -DECLARE_REF(PipelineLayout) -struct LegacyPipelineCreateInfo -{ - SePrimitiveTopology topology; - PVertexInput vertexInput; - PVertexShader vertexShader; - PFragmentShader fragmentShader; - PRenderPass renderPass; - PPipelineLayout pipelineLayout; - MultisampleState multisampleState; - RasterizationState rasterizationState; - DepthStencilState depthStencilState; - ColorBlendState colorBlend; - LegacyPipelineCreateInfo(); - ~LegacyPipelineCreateInfo(); -}; + DECLARE_REF(VertexInput) + DECLARE_REF(VertexShader) + DECLARE_REF(TaskShader) + DECLARE_REF(MeshShader) + DECLARE_REF(FragmentShader) + DECLARE_REF(ComputeShader) + DECLARE_REF(RenderPass) + DECLARE_REF(PipelineLayout) + struct LegacyPipelineCreateInfo + { + SePrimitiveTopology topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + PVertexInput vertexInput = nullptr; + PVertexShader vertexShader = nullptr; + PFragmentShader fragmentShader = nullptr; + PRenderPass renderPass = nullptr; + PPipelineLayout pipelineLayout = nullptr; + MultisampleState multisampleState; + RasterizationState rasterizationState; + DepthStencilState depthStencilState; + ColorBlendState colorBlend; + }; -struct MeshPipelineCreateInfo -{ - PTaskShader taskShader; - PMeshShader meshShader; - PFragmentShader fragmentShader; - PRenderPass renderPass; - PPipelineLayout pipelineLayout; - MultisampleState multisampleState; - RasterizationState rasterizationState; - DepthStencilState depthStencilState; - ColorBlendState colorBlend; - MeshPipelineCreateInfo(); - ~MeshPipelineCreateInfo(); -}; -struct ComputePipelineCreateInfo -{ - Gfx::PComputeShader computeShader; - Gfx::PPipelineLayout pipelineLayout; - ComputePipelineCreateInfo(); - ~ComputePipelineCreateInfo(); -}; -} // namespace Gfx + struct MeshPipelineCreateInfo + { + PTaskShader taskShader = nullptr; + PMeshShader meshShader = nullptr; + PFragmentShader fragmentShader = nullptr; + PRenderPass renderPass = nullptr; + PPipelineLayout pipelineLayout = nullptr; + MultisampleState multisampleState; + RasterizationState rasterizationState; + DepthStencilState depthStencilState; + ColorBlendState colorBlend; + }; + struct ComputePipelineCreateInfo + { + Gfx::PComputeShader computeShader = nullptr; + Gfx::PPipelineLayout pipelineLayout = nullptr; + }; + } // namespace Gfx } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 490feaa..1b04dfe 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -19,6 +19,28 @@ using namespace Seele; BasePass::BasePass(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", "MeshletPass", true, true, "BasePass", true, true, "MeshletPass"); + } + else + { + graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyPass", true, true, "BasePass"); + } } BasePass::~BasePass() @@ -58,90 +80,7 @@ void BasePass::render() graphics->beginRenderPass(renderPass); Array commands; - // Static Meshes - { - 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 (const auto& [_, mappings] : vd->getStaticMeshes()) - { - for (const auto& mapping : mappings) - { - permutation.setMaterial(mapping.material->getBaseMaterial()->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(mapping.material->getDescriptorSet()); - command->bindDescriptor(vd->getInstanceDataSet(), {0, 0}); - if (graphics->supportMeshShading()) - { - command->drawMesh(vd->getMeshData(mapping.mapped).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)); - } - } - } - // Others - { Gfx::ShaderPermutation permutation; if (graphics->supportMeshShading()) { @@ -157,7 +96,7 @@ void BasePass::render() { permutation.setVertexData(vertexData->getTypeName()); const auto& materials = vertexData->getMaterialData(); - for (const auto& [_, materialData] : materials) + for (const auto& materialData : materials) { // Create Pipeline(Material, VertexData) // Descriptors: @@ -206,7 +145,7 @@ void BasePass::render() command->bindDescriptor(viewParamsSet); command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet()); command->bindDescriptor(opaqueCulling); - for (const auto& [_, instance] : materialData.instances) + for (const auto& instance : materialData.instances) { command->bindDescriptor(instance.materialInstance->getDescriptorSet()); command->bindDescriptor(vertexData->getInstanceDataSet(), {instance.descriptorOffset, instance.descriptorOffset}); @@ -216,22 +155,22 @@ void BasePass::render() } else { - command->bindIndexBuffer(vertexData->getIndexBuffer()); - uint32 instanceOffset = 0; - for (const auto& meshData : vertexData->getMeshData(instance.meshId)) - { - if (meshData.numIndices > 0) - { - command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); - } - instanceOffset++; - } + //command->bindIndexBuffer(vertexData->getIndexBuffer()); + //uint32 instanceOffset = 0; + //for (const auto& meshData : vertexData->getMeshData(instance.meshId)) + //{ + // 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(); @@ -243,44 +182,21 @@ void BasePass::endFrame() void BasePass::publishOutputs() { - 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); 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); + Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + Gfx::SE_ATTACHMENT_LOAD_OP_LOAD, Gfx::SE_ATTACHMENT_STORE_OP_STORE); resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); - - if (graphics->supportMeshShading()) - { - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletPass", true, true, "BasePass", true, true, "MeshBasePass"); - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticMeshletPass", true, true, "BasePass", true, true, "StaticMeshletPass"); - } - else - { - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyPass", true, true, "BasePass"); - graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticLegacyPass", true, true, "BasePass"); - } } void BasePass::createRenderPass() { depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); + meshletIdAttachment = resources->requestRenderTarget("BASEPASS_MESHLETID"); depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL); + depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .colorAttachments = { colorAttachment }, + .colorAttachments = { colorAttachment, meshletIdAttachment }, .depthAttachment = depthAttachment, }; Array dependency = { @@ -297,7 +213,7 @@ void BasePass::createRenderPass() .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, + .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, }, { @@ -323,7 +239,3 @@ void BasePass::createRenderPass() oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID"); } - -void BasePass::modifyRenderPassMacros(Map&) -{ -} diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index be71986..ee900d4 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -20,6 +20,7 @@ public: private: Gfx::RenderTargetAttachment colorAttachment; Gfx::RenderTargetAttachment depthAttachment; + Gfx::RenderTargetAttachment meshletIdAttachment; Gfx::PShaderBuffer oLightIndexList; Gfx::PShaderBuffer tLightIndexList; Gfx::PTexture2D oLightGrid; @@ -27,7 +28,7 @@ private: Gfx::PDescriptorSet opaqueCulling; Gfx::PDescriptorSet transparentCulling; - //Array descriptorSets; + PCameraActor source; Gfx::OPipelineLayout basePassLayout; Gfx::ODescriptorLayout lightCullingLayout; diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 9c7be0a..d408613 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) +DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout"); @@ -29,102 +29,104 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) } DepthPrepass::~DepthPrepass() -{ +{ } -void DepthPrepass::beginFrame(const Component::Camera& cam) +void DepthPrepass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } -void DepthPrepass::render() +void DepthPrepass::render() { graphics->beginRenderPass(renderPass); Array commands; - - // Others + + Gfx::ShaderPermutation permutation; + if (graphics->supportMeshShading()) { - Gfx::ShaderPermutation permutation; - if (graphics->supportMeshShading()) + permutation.setTaskFile("MeshletPass"); + permutation.setMeshFile("MeshletPass"); + } + else + { + permutation.setVertexFile("LegacyPass"); + } + for (VertexData* vertexData : VertexData::getList()) + { + permutation.setVertexData(vertexData->getTypeName()); + const auto& materials = vertexData->getMaterialData(); + for (const auto& materialData : materials) { - permutation.setTaskFile("MeshletPass"); - permutation.setMeshFile("MeshletPass"); - } - else - { - permutation.setVertexFile("LegacyPass"); - } - for (VertexData* vertexData : VertexData::getList()) - { - permutation.setVertexData(vertexData->getTypeName()); - const auto& materials = vertexData->getMaterialData(); - for (const auto& [_, materialData] : materials) + // Create Pipeline(VertexData) + // Descriptors: + // ViewData => global, static + // VertexData => per meshtype + // SceneData => per material instance + 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()) { - // Create Pipeline(VertexData) - // Descriptors: - // ViewData => global, static - // VertexData => per meshtype - // SceneData => per material instance - permutation.setMaterial(materialData.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); + 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(vertexData->getVertexDataSet()); + command->bindDescriptor(viewParamsSet); + for (const auto& instance : materialData.instances) + { + command->bindDescriptor(vertexData->getInstanceDataSet(), { instance.descriptorOffset, instance.descriptorOffset }); 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; - pipelineInfo.multisampleState.samples = viewport->getSamples(); - pipelineInfo.colorBlend.attachmentCount = 1; - Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); - command->bindPipeline(pipeline); + command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1); } 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->bindIndexBuffer(vertexData->getIndexBuffer()); + //uint32 instanceOffset = 0; + //for (const auto& meshData : vertexData->getMeshData(instance.meshId)) + //{ + // if (meshData.numIndices > 0) + // { + // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); + // } + // instanceOffset++; + //} } - command->bindDescriptor(vertexData->getVertexDataSet()); - command->bindDescriptor(viewParamsSet); - for (const auto& [_, instance] : materialData.instances) - { - command->bindDescriptor(vertexData->getInstanceDataSet(), { instance.descriptorOffset, instance.descriptorOffset }); - if (graphics->supportMeshShading()) - { - command->drawMesh(vertexData->getMeshData(instance.meshId).size(), 1, 1); - } - else - { - command->bindIndexBuffer(vertexData->getIndexBuffer()); - uint32 instanceOffset = 0; - for (const auto& meshData : vertexData->getMeshData(instance.meshId)) - { - if (meshData.numIndices > 0) - { - command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); - } - instanceOffset++; - } - } - } - commands.add(std::move(command)); } + commands.add(std::move(command)); } } @@ -132,14 +134,48 @@ void DepthPrepass::render() graphics->endRenderPass(); } -void DepthPrepass::endFrame() +void DepthPrepass::endFrame() { } -void DepthPrepass::publishOutputs() +void DepthPrepass::publishOutputs() { } -void DepthPrepass::createRenderPass() +void DepthPrepass::createRenderPass() { + depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); + depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); + depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL); + 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_COMPUTE_SHADER_BIT, + .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .dstAccess = Gfx::SE_ACCESS_SHADER_READ_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), std::move(dependency), viewport); } diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index ffeac57..cc19630 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -18,9 +18,7 @@ public: virtual void createRenderPass() override; private: Gfx::RenderTargetAttachment depthAttachment; - Gfx::OTexture2D depthBuffer; Gfx::OPipelineLayout depthPrepassLayout; - Gfx::ODescriptorLayout sceneDataLayout; }; DEFINE_REF(DepthPrepass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 03cfd9f..5bd5de3 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -189,9 +189,6 @@ void LightCullingPass::createRenderPass() depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH").getTexture(); } -void LightCullingPass::modifyRenderPassMacros(Map&) -{ -} void LightCullingPass::setupFrustums() { diff --git a/src/Engine/Graphics/RenderPass/StaticBasePass.cpp b/src/Engine/Graphics/RenderPass/StaticBasePass.cpp index e69de29..238f5ce 100644 --- a/src/Engine/Graphics/RenderPass/StaticBasePass.cpp +++ b/src/Engine/Graphics/RenderPass/StaticBasePass.cpp @@ -0,0 +1,227 @@ +#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", true, true, "BasePass", true); + } + else + { + graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "StaticBasePass", "StaticLegacyPass", true, 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); + + meshletIdTexture = graphics->createTexture2D(TextureCreateInfo{ + .format = Gfx::SE_FORMAT_R32_UINT, + .width = viewport->getWidth(), + .height = viewport->getHeight(), + .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_STORAGE_BIT, + }); + meshletIdAttachment = Gfx::RenderTargetAttachment(meshletIdTexture, + 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_MESHLETID", meshletIdAttachment); +} + +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 index e69de29..299222f 100644 --- a/src/Engine/Graphics/RenderPass/StaticBasePass.h +++ b/src/Engine/Graphics/RenderPass/StaticBasePass.h @@ -0,0 +1,37 @@ +#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 index 09da9a8..831f0b2 100644 --- a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/StaticDepthPrepass.cpp @@ -7,11 +7,16 @@ 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, true, "MeshletPass"); + graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true); } else { @@ -30,82 +35,95 @@ void StaticDepthPrepass::beginFrame(const Component::Camera& cam) void StaticDepthPrepass::render() { - // Static Meshes + Array commands; + graphics->beginRenderPass(renderPass); + + Gfx::ShaderPermutation permutation; + if (graphics->supportMeshShading()) { - Gfx::ShaderPermutation permutation; + 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()) { - permutation.setTaskFile("StaticMeshletPass"); - permutation.setMeshFile("StaticMeshletPass"); + 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 { - permutation.setVertexFile("LegacyPass"); + 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); } - StaticMeshVertexData* vd = StaticMeshVertexData::getInstance(); - permutation.setVertexData(vd->getTypeName()); - for (const auto& [_, mappings] : vd->) + command->bindDescriptor(viewParamsSet); + command->bindDescriptor(vd->getVertexDataSet()); + command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 }); + for (const auto& instance : mesh.staticInstance) { - permutation.setMaterial(mapping.material->getBaseMaterial()->getName()); - 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; - 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(viewParamsSet); - command->bindDescriptor(vd->getVertexDataSet()); - command->bindDescriptor(vd->getInstanceDataSet(), { 0, 0 }); - if (graphics->supportMeshShading()) - { - command->drawMesh(vd->getMeshData(mapping.mapped).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)); + 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() @@ -125,7 +143,7 @@ void StaticDepthPrepass::publishOutputs() depthBuffer = graphics->createTexture2D(depthBufferInfo); depthAttachment = Gfx::RenderTargetAttachment(depthBuffer, - Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_GENERAL, + Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment); } @@ -144,14 +162,6 @@ void StaticDepthPrepass::createRenderPass() .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_COMPUTE_SHADER_BIT, - .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - .dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT, - }, { .srcSubpass = 0, .dstSubpass = ~0U, diff --git a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h b/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h index 6f2fa1b..b456a22 100644 --- a/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/StaticDepthPrepass.h @@ -19,6 +19,6 @@ private: Gfx::RenderTargetAttachment depthAttachment; Gfx::OTexture2D depthBuffer; Gfx::OPipelineLayout depthPrepassLayout; - Gfx::ODescriptorLayout sceneDataLayout; + Gfx::ODescriptorLayout meshletCullingLayout; }; } \ No newline at end of file diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index fb47e09..a1c35db 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -153,12 +153,12 @@ void StaticMeshVertexData::init(Gfx::PGraphics _graphics) { VertexData::init(_graphics); descriptorLayout = _graphics->createDescriptorLayout("pVertexData"); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS }); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS }); descriptorLayout->create(); descriptorSet = descriptorLayout->allocateDescriptorSet(); } @@ -193,14 +193,13 @@ Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() return descriptorSet; } -void StaticMeshVertexData::registerStaticMesh(entt::entity id, const Array& meshes, const Component::Transform& transform) +void StaticMeshVertexData::registerStaticMesh(const Array& meshes, const Component::Transform& transform) { - std::unique_lock l(vertexDataLock); - std::unique_lock l2(mutex); for (auto& mesh : meshes) { uint64 numVertices = meshVertexCounts[mesh->id]; uint64 offset = meshOffsets[mesh->id]; + // Create new mesh where transform is "embedded" MeshId mapped = VertexData::allocateVertexData(numVertices); Array pos(numVertices); Matrix4 matrix = transform.toMatrix(); @@ -222,10 +221,40 @@ void StaticMeshVertexData::registerStaticMesh(entt::entity id, const Arrayid, - .mapped = mapped, - .material = mesh->referencedMaterial->getHandle(), + + // Load meshlets again + VertexData::loadMesh(mapped, mesh->indices, mesh->meshlets); + + Array ids; + // Get references to loaded meshlets + const auto& meshData = VertexData::getMeshData(mapped); + for (const auto& md : meshData) + { + for (size_t i = 0; i < md.numMeshlets; ++i) + { + ids.add(md.meshletOffset + i); + } + } + + // Get Static instance array + PMaterialInstance instance = mesh->referencedMaterial->getHandle(); + PMaterial baseMat = instance->getBaseMaterial(); + Array instances; + instances.add(StaticMatInstance{ + .instance = mesh->referencedMaterial->getHandle(), + .meshletIds = ids, + .culledMeshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .sourceData = { + .size = ids.size() * sizeof(uint32), + .data = (uint8*)ids.data(), + }, + .numElements = ids.size(), + .dynamic = true, + }), + }); + staticData.add(StaticMatData{ + .material = baseMat, + .staticInstance = std::move(instances), }); } } @@ -257,7 +286,7 @@ void StaticMeshVertexData::resizeBuffers() texCoords[i] = graphics->createShaderBuffer(createInfo); texCoordsData[i].resize(verticesAllocated); } - + positionData.resize(verticesAllocated); normalData.resize(verticesAllocated); tangentData.resize(verticesAllocated); diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 20696fd..76cfe2e 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -10,11 +10,17 @@ namespace Seele class StaticMeshVertexData : public VertexData { public: - struct StaticMeshMapping + struct StaticMatInstance { - MeshId original; - MeshId mapped; - PMaterialInstance material; + PMaterialInstance instance; + Array meshletIds; + Gfx::OShaderBuffer culledMeshletBuffer; + //Gfx::OShaderBuffer indirectDrawBuffer; + }; + struct StaticMatData + { + PMaterial material; + Array staticInstance; }; StaticMeshVertexData(); virtual ~StaticMeshVertexData(); @@ -34,10 +40,11 @@ public: virtual Gfx::PDescriptorSet getVertexDataSet() override; virtual std::string getTypeName() const override { return "StaticMeshVertexData"; } void registerStaticMesh(const Array& meshes, const Component::Transform& transform); + constexpr const Array& getStaticMeshes() const { return staticData; } private: virtual void resizeBuffers() override; virtual void updateBuffers() override; - Array staticMeshlets; + Array staticData; std::mutex mutex; Gfx::OShaderBuffer positions; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index 6a15ae5..25d0c7f 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -16,7 +16,7 @@ constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024; void VertexData::resetMeshData() { std::unique_lock l(materialDataLock); - for (auto& [_, mat] : materialData) + for (auto& mat : materialData) { mat.material->getDescriptorLayout()->reset(); } @@ -33,7 +33,11 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform) std::unique_lock l(materialDataLock); PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle(); PMaterial mat = referencedInstance->getBaseMaterial(); - MaterialData& matData = materialData[mat->getName()]; + if (materialData.size() <= mat->getId()) + { + materialData.resize(mat->getId()); + } + MaterialData& matData = materialData[mat->getId()]; matData.material = mat; MaterialInstanceData& matInstanceData = matData.instances[referencedInstance->getId()]; matInstanceData.descriptorOffset = instanceData.size(); @@ -166,13 +170,13 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array .vertexOffset = vertexOffset, .primitiveOffset = primitiveOffset, .color = Vector((float)rand() / RAND_MAX,(float)rand() / RAND_MAX,(float)rand() / RAND_MAX), + .indicesOffset = (uint32)meshOffsets[id], }); } meshData[id].add(MeshData{ .bounding = meshAABB,//.toSphere(), .numMeshlets = numMeshlets, .meshletOffset = meshletOffset, - .indicesOffset = (uint32)meshOffsets[id], }); currentMesh += numMeshlets; } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index f8171b5..27c6f39 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -40,8 +40,6 @@ public: uint32 meshletOffset = 0; uint32 firstIndex = 0; uint32 numIndices = 0; - uint32 indicesOffset = 0; - uint32 pad0[3]; }; struct MaterialInstanceData { @@ -53,7 +51,7 @@ public: struct MaterialData { PMaterial material; - Map instances; + Array instances; }; void resetMeshData(); void updateMesh(PMesh mesh, Component::Transform& transform); @@ -71,7 +69,7 @@ public: Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; } Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; } Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; } - const Map& getMaterialData() const { return materialData; } + const Array& getMaterialData() const { return materialData; } const Array& getMeshData(MeshId id) { return meshData[id]; } static List getList(); static VertexData* findByTypeName(std::string name); @@ -89,10 +87,10 @@ protected: uint32 vertexOffset; uint32 primitiveOffset; Vector color; - float pad; + uint32 indicesOffset = 0; }; std::mutex materialDataLock; - Map materialData; + Array materialData; std::mutex vertexDataLock; Map> meshData; Map meshOffsets; diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 73315c6..0c5d4f4 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -207,16 +207,19 @@ void Buffer::createBuffer() .usage = VMA_MEMORY_USAGE_AUTO, }; buffers.add(); - vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back().buffer, &buffers.back().allocation, - &buffers.back().info); - vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back().allocation, &buffers.back().properties); - if (!name.empty()) { - VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, - .pNext = nullptr, - .objectType = VK_OBJECT_TYPE_BUFFER, - .objectHandle = (uint64)buffers.back().buffer, - .pObjectName = this->name.c_str() }; - graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo); + if (size > 0) + { + VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back().buffer, &buffers.back().allocation, + &buffers.back().info)); + vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back().allocation, &buffers.back().properties); + if (!name.empty()) { + VkDebugUtilsObjectNameInfoEXT nameInfo = { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .pNext = nullptr, + .objectType = VK_OBJECT_TYPE_BUFFER, + .objectHandle = (uint64)buffers.back().buffer, + .pObjectName = this->name.c_str() }; + graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo); + } } } @@ -224,7 +227,7 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData), Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic, createInfo.name) { - if (createInfo.sourceData.data != nullptr) { + if (size > 0 && createInfo.sourceData.data != nullptr) { void* data = map(); std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); unmap(); @@ -265,7 +268,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sou : Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic, sourceData.name) { - if (sourceData.sourceData.data != nullptr) { + if (size > 0 && sourceData.sourceData.data != nullptr) { void* data = map(); std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); unmap(); diff --git a/src/Engine/Graphics/Vulkan/Command.cpp b/src/Engine/Graphics/Vulkan/Command.cpp index 2f90de1..2102556 100644 --- a/src/Engine/Graphics/Vulkan/Command.cpp +++ b/src/Engine/Graphics/Vulkan/Command.cpp @@ -340,6 +340,12 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ); } +void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) +{ + assert(threadId == std::this_thread::get_id()); + graphics->vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast()->getHandle(), offset, drawCount, stride); +} + ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics) , owner(cmdPool) diff --git a/src/Engine/Graphics/Vulkan/Command.h b/src/Engine/Graphics/Vulkan/Command.h index e0af7a4..510e7f8 100644 --- a/src/Engine/Graphics/Vulkan/Command.h +++ b/src/Engine/Graphics/Vulkan/Command.h @@ -82,6 +82,7 @@ public: virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override; virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override; + virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override; private: PGraphicsPipeline pipeline; diff --git a/src/Engine/Graphics/Vulkan/Enums.h b/src/Engine/Graphics/Vulkan/Enums.h index 098ddfb..940beb9 100644 --- a/src/Engine/Graphics/Vulkan/Enums.h +++ b/src/Engine/Graphics/Vulkan/Enums.h @@ -14,7 +14,7 @@ std::this_thread::sleep_for(std::chrono::seconds(3)); \ } \ std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \ - assert(res == VK_SUCCESS); \ + abort(); \ } \ } diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 41f2830..67ca28d 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -298,6 +298,11 @@ void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint cmdDrawMeshTasks(handle, groupX, groupY, groupZ); } +void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) +{ + cmdDrawMeshTasksIndirect(handle, buffer, offset, drawCount, stride); +} + void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info) { VK_CHECK(setDebugUtilsObjectName(handle, info)); @@ -617,28 +622,6 @@ void Graphics::createDevice(GraphicsInitializer initializer) queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex)); } - // if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1) - // { - // if (asyncComputeInfo.familyIndex == graphicsQueueInfo.familyIndex) - // { - // // Same family as graphics, but different queue - // computeQueue = new Queue(this, asyncComputeInfo.familyIndex, 1); - // } - // else - // { - // // Different family - // computeQueue = new Queue(this, asyncComputeInfo.familyIndex, 0); - // } - // } - // else - // { - // computeQueue = new Queue(this, computeQueueInfo.familyIndex, 0); - // } - // transferQueue = new Queue(this, transferQueueInfo.familyIndex, 0); - // if (dedicatedTransferQueueInfo.familyIndex != -1) - // { - // dedicatedTransferQueue = new Queue(this, dedicatedTransferQueueInfo.familyIndex, 0); - // } queueMapping.graphicsFamily = queues[graphicsQueue]->getFamilyIndex(); queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex(); queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex(); diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index 2f2e507..4179449 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -71,10 +71,12 @@ public: virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override; void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ); + void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride); void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info); protected: PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks; + PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect; PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName; Array getRequiredExtensions(); void initInstance(GraphicsInitializer initInfo); diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 1f82fe6..14e282b 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -9,6 +9,9 @@ using namespace Seele; +std::atomic_uint64_t Material::materialIdCounter = 0; +Array Material::materials; + Material::Material() { } @@ -30,7 +33,9 @@ Material::Material(Gfx::PGraphics graphics, , codeExpressions(std::move(expressions)) , parameters(std::move(parameter)) , brdf(std::move(brdf)) + , materialId(materialIdCounter++) { + materials.add(this); } Material::~Material() diff --git a/src/Engine/Material/Material.h b/src/Engine/Material/Material.h index 5a74b22..26769be 100644 --- a/src/Engine/Material/Material.h +++ b/src/Engine/Material/Material.h @@ -22,6 +22,8 @@ public: Gfx::PDescriptorLayout getDescriptorLayout() { return layout; } OMaterialInstance instantiate(); const std::string& getName() const { return materialName; } + constexpr const uint64 getId() const { return materialId; } + static constexpr const PMaterial findMaterialById(uint64 id) { return materials[id]; } void save(ArchiveBuffer& buffer) const; void load(ArchiveBuffer& buffer); @@ -33,11 +35,14 @@ private: uint32 uniformDataSize; uint32 uniformBinding; uint64 instanceId; + uint64 materialId; Gfx::ODescriptorLayout layout; std::string materialName; Array codeExpressions; Array parameters; MaterialNode brdf; + static std::atomic_uint64_t materialIdCounter; + static Array materials; }; DEFINE_REF(Material) diff --git a/src/Engine/System/MeshUpdater.cpp b/src/Engine/System/MeshUpdater.cpp index ace1b8e..4f48727 100644 --- a/src/Engine/System/MeshUpdater.cpp +++ b/src/Engine/System/MeshUpdater.cpp @@ -18,6 +18,9 @@ void MeshUpdater::update(Component::Transform& transform, Component::Mesh& comp) { for (auto& mesh : comp.asset->meshes) { - mesh->vertexData->updateMesh(mesh, transform); + if (!comp.isStatic) + { + mesh->vertexData->updateMesh(mesh, transform); + } } } diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 1821033..78562c4 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -18,8 +18,10 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate , gameInterface(dllPath) { reloadGame(); + renderGraph.addPass(new StaticDepthPrepass(graphics, scene)); renderGraph.addPass(new DepthPrepass(graphics, scene)); renderGraph.addPass(new LightCullingPass(graphics, scene)); + renderGraph.addPass(new StaticBasePass(graphics, scene)); renderGraph.addPass(new BasePass(graphics, scene)); //renderGraph.addPass(new DebugPass(graphics, scene)); //renderGraph.addPass(new SkyboxRenderPass(graphics, scene)); diff --git a/src/Engine/Window/GameView.h b/src/Engine/Window/GameView.h index ac1357d..9a89aaf 100644 --- a/src/Engine/Window/GameView.h +++ b/src/Engine/Window/GameView.h @@ -6,6 +6,8 @@ #include "Graphics/RenderPass/BasePass.h" #include "Graphics/RenderPass/SkyboxRenderPass.h" #include "Graphics/RenderPass/DebugPass.h" +#include "Graphics/RenderPass/StaticDepthPrepass.h" +#include "Graphics/RenderPass/StaticBasePass.h" #include "System/KeyboardInput.h" #ifdef WIN32 #include "Platform/Windows/GameInterface.h" // TODO